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 2026/03/13 23:10:02 UTC
(tinkerpop) branch js-translator created (now 8f32db2294)
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a change to branch js-translator
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
at 8f32db2294 Added docs for gremlin-mcp and javascript translator
This branch includes the following new commits:
new c4c136b8d7 Added Translator infrastructure to gremlin-javascript
new 76f4fa937e Added translator tool to gremlin-mcp
new 8f32db2294 Added docs for gremlin-mcp and javascript translator
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(tinkerpop) 01/03: Added Translator infrastructure to gremlin-javascript
Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch js-translator
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit c4c136b8d7d4d77f655b2a73033877a2f1f08e23
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Mon Mar 9 09:22:50 2026 -0400
Added Translator infrastructure to gremlin-javascript
---
.../main/javascript/gremlin-javascript/.gitignore | 4 +-
.../gremlin-javascript/lib/language/index.ts | 31 +
.../gremlin-javascript/lib/language/package.json | 1 +
.../translator/AnonymizedTranslateVisitor.ts | 160 +
.../language/translator/DotNetTranslateVisitor.ts | 891 +
.../lib/language/translator/GoTranslateVisitor.ts | 375 +
.../lib/language/translator/GremlinTranslator.ts | 110 +
.../language/translator/GroovyTranslateVisitor.ts | 295 +
.../language/translator/JavaTranslateVisitor.ts | 261 +
.../translator/JavascriptTranslateVisitor.ts | 232 +
.../language/translator/PythonTranslateVisitor.ts | 321 +
.../lib/language/translator/TranslateVisitor.ts | 440 +
.../lib/language/translator/Translation.ts | 45 +
.../lib/language/translator/Translator.ts | 46 +
.../lib/language/translator/TranslatorException.ts | 28 +
.../javascript/gremlin-javascript/licenses/buffer | 21 -
.../gremlin-javascript/licenses/eventemitter3 | 21 -
.../gremlin-javascript/licenses/readable-stream | 47 -
.../javascript/gremlin-javascript/licenses/uuid | 9 -
.../main/javascript/gremlin-javascript/licenses/ws | 20 -
.../gremlin-javascript/package-lock.json | 801 +-
.../javascript/gremlin-javascript/package.json | 22 +-
.../gremlin-javascript/scripts/patch-antlr4ng.js | 60 +
.../test/unit/translator/corpus-test.js | 158 +
.../unit/translator/gremlin-translator-test.js | 550 +
gremlin-mcp/src/main/javascript/package-lock.json | 66 +-
gremlin-test/build/generate-translator-data.groovy | 56 +
gremlin-test/pom.xml | 50 +
.../gremlin/language/translator/translations.json | 40985 +++++++++++++++++++
pom.xml | 7 +-
30 files changed, 45755 insertions(+), 358 deletions(-)
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore b/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore
index 4a67f551e6..ee0fff034d 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore
@@ -4,4 +4,6 @@ npm-debug.log
# maven plugin com.github.eirslett frontend-maven-plugin installs node.js runtime in "node" folder
node/
doc/
-build/
\ No newline at end of file
+build/
+lib/language/grammar/
+**/.duel-cache/
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/index.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/index.ts
new file mode 100644
index 0000000000..306b8dd4b5
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/index.ts
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export { GremlinTranslator } from './translator/GremlinTranslator.js';
+export { Translation } from './translator/Translation.js';
+export { TranslatorException } from './translator/TranslatorException.js';
+export { Translator } from './translator/Translator.js';
+export { default as TranslateVisitor } from './translator/TranslateVisitor.js';
+export { default as JavascriptTranslateVisitor } from './translator/JavascriptTranslateVisitor.js';
+export { default as PythonTranslateVisitor } from './translator/PythonTranslateVisitor.js';
+export { default as GoTranslateVisitor } from './translator/GoTranslateVisitor.js';
+export { default as DotNetTranslateVisitor } from './translator/DotNetTranslateVisitor.js';
+export { default as JavaTranslateVisitor } from './translator/JavaTranslateVisitor.js';
+export { default as GroovyTranslateVisitor } from './translator/GroovyTranslateVisitor.js';
+export { default as AnonymizedTranslateVisitor } from './translator/AnonymizedTranslateVisitor.js';
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/package.json
new file mode 100644
index 0000000000..5ffd9800b9
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/package.json
@@ -0,0 +1 @@
+{ "type": "module" }
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/AnonymizedTranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/AnonymizedTranslateVisitor.ts
new file mode 100644
index 0000000000..4f90e986fa
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/AnonymizedTranslateVisitor.ts
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Context parameters are typed as `any` because the generated grammar files
+// require accepting arbitrary context types at runtime.
+
+import TranslateVisitor from './TranslateVisitor.js';
+
+/**
+ * Anonymizes a Gremlin traversal by replacing literal values with type-based
+ * placeholders (e.g. `string0`, `number1`). Identical values within the same
+ * traversal reuse the same placeholder. Mirrors the Java AnonymizedTranslatorVisitor.
+ */
+export default class AnonymizedTranslateVisitor extends TranslateVisitor {
+
+ /** outer key: Java simple class name (e.g. "String"); inner key: original text → placeholder */
+ private readonly cache: Map<string, Map<string, string>> = new Map();
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ super(graphTraversalSourceName);
+ }
+
+ /**
+ * Replaces the text of `ctx` with a type-tagged placeholder.
+ * The first unique value of each type gets index 0, the second index 1, etc.
+ * Repeated occurrences of the same text reuse the same placeholder.
+ *
+ * @param ctx ANTLR parse-tree context whose getText() is used as the cache key
+ * @param type Java simple class name (e.g. "String", "Integer", "Number")
+ */
+ protected anonymize(ctx: any, type: string): void {
+ const text: string = ctx.getText();
+
+ let inner = this.cache.get(type);
+ if (inner === undefined) {
+ inner = new Map<string, string>();
+ this.cache.set(type, inner);
+ }
+
+ let placeholder = inner.get(text);
+ if (placeholder === undefined) {
+ placeholder = type.toLowerCase() + inner.size;
+ inner.set(text, placeholder);
+ }
+
+ this.sb.push(placeholder);
+ }
+
+ // ─── Collection / map literals ───────────────────────────────────────────
+
+ visitGenericSetLiteral(ctx: any): void {
+ this.anonymize(ctx, 'Set');
+ }
+
+ visitGenericCollectionLiteral(ctx: any): void {
+ this.anonymize(ctx, 'List');
+ }
+
+ visitGenericMapLiteral(ctx: any): void {
+ this.anonymize(ctx, 'Map');
+ }
+
+ visitGenericMapNullableArgument(ctx: any): void {
+ this.anonymize(ctx, 'Map');
+ }
+
+ // ─── String literals ─────────────────────────────────────────────────────
+
+ visitStringLiteral(ctx: any): void {
+ this.anonymize(ctx, 'String');
+ }
+
+ visitStringNullableLiteral(ctx: any): void {
+ this.anonymize(ctx, 'String');
+ }
+
+ // ─── Numeric literals ────────────────────────────────────────────────────
+
+ visitIntegerLiteral(ctx: any): void {
+ const lastChar = ctx.getText().toLowerCase().slice(-1);
+ switch (lastChar) {
+ case 'b': this.anonymize(ctx, 'Byte'); break;
+ case 's': this.anonymize(ctx, 'Short'); break;
+ case 'i': this.anonymize(ctx, 'Integer'); break;
+ case 'l': this.anonymize(ctx, 'Long'); break;
+ case 'n': this.anonymize(ctx, 'BigInteger'); break;
+ default: this.anonymize(ctx, 'Number'); break;
+ }
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ // Do NOT delegate to infLiteral/nanLiteral — anonymize the FloatLiteralContext directly
+ const lastChar = ctx.getText().toLowerCase().slice(-1);
+ switch (lastChar) {
+ case 'f': this.anonymize(ctx, 'Float'); break;
+ case 'd': this.anonymize(ctx, 'Double'); break;
+ case 'm': this.anonymize(ctx, 'BigDecimal'); break;
+ default: this.anonymize(ctx, 'Number'); break;
+ }
+ }
+
+ // ─── Other literals ──────────────────────────────────────────────────────
+
+ visitBooleanLiteral(ctx: any): void {
+ this.anonymize(ctx, 'Boolean');
+ }
+
+ visitDateLiteral(ctx: any): void {
+ this.anonymize(ctx, 'OffsetDateTime');
+ }
+
+ visitNullLiteral(ctx: any): void {
+ this.anonymize(ctx, 'Object');
+ }
+
+ visitNanLiteral(ctx: any): void {
+ this.anonymize(ctx, 'Number');
+ }
+
+ visitInfLiteral(ctx: any): void {
+ this.anonymize(ctx, 'Number');
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ this.anonymize(ctx, 'String');
+ }
+
+ // ─── Keys — output unquoted (only values are anonymized) ─────────────────
+
+ visitNakedKey(ctx: any): void {
+ this.sb.push(ctx.getText());
+ }
+
+ visitKeyword(ctx: any): void {
+ const keyword: string = ctx.getText();
+ const parentName = ctx.parent?.constructor?.name ?? '';
+ if (parentName === 'MapKeyContext' || parentName === 'ConfigurationContext') {
+ this.sb.push(keyword);
+ } else {
+ this.sb.push(keyword);
+ this.sb.push(' ');
+ }
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/DotNetTranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/DotNetTranslateVisitor.ts
new file mode 100644
index 0000000000..11e303144f
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/DotNetTranslateVisitor.ts
@@ -0,0 +1,891 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Context parameters are typed as `any` because the generated grammar files
+// require accepting arbitrary context types at runtime.
+
+import TranslateVisitor from './TranslateVisitor.js';
+import { TranslatorException } from './TranslatorException.js';
+
+// Steps whose return type needs <object, object>
+const DOUBLE_GENERIC_STEPS = new Set(['group', 'valueMap']);
+
+/**
+ * Converts a Gremlin traversal string into a C# source code representation.
+ * Mirrors the Java DotNetTranslateVisitor.
+ */
+export default class DotNetTranslateVisitor extends TranslateVisitor {
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ super(graphTraversalSourceName);
+ }
+
+ protected override processGremlinSymbol(step: string): string {
+ return SymbolHelper.toCSharp(step);
+ }
+
+ protected override getCardinalityFunctionClass(): string {
+ return 'CardinalityValue';
+ }
+
+ /**
+ * .NET enum values are capitalized but do NOT go through processGremlinSymbol,
+ * since the SymbolHelper mappings (bigdecimal→BigDecimal etc.) don't apply to enums.
+ */
+ protected override appendExplicitNaming(txt: string, prefix: string): void {
+ if (!txt.startsWith(prefix + '.')) {
+ this.sb.push(prefix);
+ this.sb.push('.');
+ this.sb.push(capitalize(txt));
+ } else {
+ const parts = txt.split('.');
+ this.sb.push(parts[0]);
+ this.sb.push('.');
+ this.sb.push(capitalize(parts[1]));
+ }
+ }
+
+ visitTraversalGType(ctx: any): void {
+ const parts: string[] = ctx.getText().split('.');
+ this.sb.push(this.processGremlinSymbol(parts[0]));
+ this.sb.push('.');
+ this.sb.push(this.processGremlinSymbol(parts[1].toLowerCase()));
+ }
+
+ visitTraversalDirection(ctx: any): void {
+ const direction = ctx.getText().toLowerCase();
+ this.sb.push('Direction.');
+ if (direction.includes('out')) this.sb.push('Out');
+ else if (direction.includes('in')) this.sb.push('In');
+ else if (direction.includes('from')) this.sb.push('From');
+ else if (direction.includes('to')) this.sb.push('To');
+ else this.sb.push('Both');
+ }
+
+ visitTraversalDirectionShort(ctx: any): void {
+ this.visitTraversalDirection(ctx);
+ }
+
+ visitTraversalDirectionLong(ctx: any): void {
+ this.visitTraversalDirection(ctx);
+ }
+
+ visitNanLiteral(_ctx: any): void {
+ this.sb.push('Double.NaN');
+ }
+
+ visitInfLiteral(ctx: any): void {
+ if (ctx.SignedInfLiteral() != null && ctx.SignedInfLiteral().getText() === '-Infinity') {
+ this.sb.push('Double.NegativeInfinity');
+ } else {
+ this.sb.push('Double.PositiveInfinity');
+ }
+ }
+
+ visitIntegerLiteral(ctx: any): void {
+ const integerLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = integerLiteral[integerLiteral.length - 1];
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(integerLiteral);
+ return;
+ }
+
+ const num = integerLiteral.slice(0, -1);
+ switch (lastChar) {
+ case 'b':
+ this.sb.push('(sbyte) ');
+ this.sb.push(num);
+ break;
+ case 's':
+ this.sb.push('(short) ');
+ this.sb.push(num);
+ break;
+ case 'i':
+ this.sb.push(num);
+ break;
+ case 'l':
+ this.sb.push(integerLiteral); // keep the 'l' suffix for C#
+ break;
+ case 'n':
+ this.sb.push('BigInteger.Parse("');
+ this.sb.push(num);
+ this.sb.push('")');
+ break;
+ default:
+ this.sb.push(integerLiteral);
+ }
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ if (ctx.infLiteral() != null) { this.visit(ctx.infLiteral()); return; }
+ if (ctx.nanLiteral() != null) { this.visit(ctx.nanLiteral()); return; }
+
+ const floatLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = floatLiteral[floatLiteral.length - 1];
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(floatLiteral);
+ return;
+ }
+
+ const num = floatLiteral.slice(0, -1);
+ switch (lastChar) {
+ case 'f':
+ case 'd':
+ this.sb.push(floatLiteral); // keep the f/d suffix for C#
+ break;
+ case 'm':
+ this.sb.push('(decimal) ');
+ this.sb.push(num);
+ break;
+ default:
+ this.sb.push(floatLiteral);
+ }
+ }
+
+ visitDateLiteral(ctx: any): void {
+ const dtString: string = ctx.getChild(2).getText();
+ const inner = TranslateVisitor.removeFirstAndLastCharacters(dtString);
+ this.sb.push('DateTimeOffset.Parse("');
+ this.sb.push(formatDatetimeJavaStyle(inner));
+ this.sb.push('")');
+ }
+
+ visitGenericRangeLiteral(_ctx: any): void {
+ throw new TranslatorException('.NET does not support range literals');
+ }
+
+ visitGenericSetLiteral(ctx: any): void {
+ this.sb.push('new HashSet<object> { ');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) this.sb.push(', ');
+ }
+ this.sb.push(' }');
+ }
+
+ visitGenericCollectionLiteral(ctx: any): void {
+ this.sb.push('new List<object> { ');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) this.sb.push(', ');
+ }
+ this.sb.push(' }');
+ }
+
+ visitGenericMapLiteral(ctx: any): void {
+ this.sb.push('new Dictionary<object, object> {');
+ const entries: any[] = ctx.mapEntry();
+ for (let i = 0; i < entries.length; i++) {
+ this.visit(entries[i]);
+ if (i < entries.length - 1) this.sb.push(', ');
+ }
+ this.sb.push('}');
+ }
+
+ visitMapEntry(ctx: any): void {
+ this.sb.push('{ ');
+ this.visit(ctx.mapKey());
+ this.sb.push(', ');
+ this.visit(ctx.genericLiteral());
+ this.sb.push(' }');
+ }
+
+ visitMapKey(ctx: any): void {
+ const keyIndex = (ctx.LPAREN() != null && ctx.RPAREN() != null) ? 1 : 0;
+ this.visit(ctx.getChild(keyIndex));
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ if (ctx.stringLiteral() == null) {
+ this.sb.push('Guid.NewGuid()');
+ return;
+ }
+ this.sb.push('Guid.Parse(');
+ this.sb.push(ctx.stringLiteral().getText());
+ this.sb.push(')');
+ }
+
+ visitClassType(ctx: any): void {
+ this.sb.push('typeof(');
+ this.sb.push(ctx.getText());
+ this.sb.push(')');
+ }
+
+ visitTraversalStrategy(ctx: any): void {
+ if (ctx.getChildCount() === 1) {
+ this.sb.push('new ');
+ this.sb.push(ctx.getText());
+ this.sb.push('()');
+ return;
+ }
+
+ const firstText = ctx.getChild(0).getText();
+ const strategyName = firstText === 'new' ? ctx.getChild(1).getText() : firstText;
+ this.sb.push('new ');
+ this.sb.push(strategyName);
+ this.sb.push('(');
+
+ const configs: any[] = ctx.configuration();
+ const isOptionsStrategy = ctx.children?.some((c: any) => c.getText() === 'OptionsStrategy');
+
+ if (configs.length > 0 && isOptionsStrategy) {
+ this.sb.push('new Dictionary<string, object> {');
+ for (const cfg of configs) {
+ this.sb.push('{"');
+ this.sb.push(cfg.getChild(0).getText());
+ this.sb.push('",');
+ this.visit(cfg.getChild(2));
+ this.sb.push('},');
+ }
+ this.sb.push('}');
+ } else {
+ for (let ix = 0; ix < configs.length; ix++) {
+ this.visit(configs[ix]);
+ if (ix < configs.length - 1) this.sb.push(', ');
+ }
+ }
+
+ this.sb.push(')');
+ }
+
+ visitConfiguration(ctx: any): void {
+ const key: string = ctx.getChild(0).getText();
+ this.sb.push(key);
+ this.sb.push(': ');
+
+ const startIdx = this.sb.length;
+ this.visit(ctx.getChild(2));
+
+ if (key === 'readPartitions') {
+ const added = this.sb.splice(startIdx);
+ this.sb.push(added.join('').replace('List<object>', 'HashSet<string>'));
+ } else if (key === 'keys') {
+ const added = this.sb.splice(startIdx);
+ const joined = added.join('');
+ this.sb.push(joined.includes('HashSet<object>') ? joined.replace('HashSet<object>', 'HashSet<string>') : joined);
+ }
+ }
+
+ visitStringNullableArgumentVarargs(ctx: any): void {
+ const n = ctx.getChildCount();
+ for (let ix = 0; ix < n; ix++) {
+ const child = ctx.getChild(ix);
+ if (child.constructor?.name === 'StringNullableArgumentContext') {
+ this.tryAppendCastToString_StringNullableArg(child);
+ }
+ this.visit(child);
+ }
+ }
+
+ // ─── handleGenerics helpers ─────────────────────────────────────────────
+
+ private handleGenerics(ctx: any): void {
+ const step: string = ctx.getChild(0).getText();
+ this.sb.push(capitalize(step));
+ this.sb.push(DOUBLE_GENERIC_STEPS.has(step) ? '<object, object>' : '<object>');
+ for (let ix = 1; ix < ctx.getChildCount(); ix++) {
+ this.visit(ctx.getChild(ix));
+ }
+ }
+
+ private handleLongArguments(ctx: any): void {
+ const step: string = ctx.getChild(0).getText();
+ this.sb.push(capitalize(step));
+ this.sb.push('<object>');
+ for (let ix = 1; ix < ctx.getChildCount(); ix++) {
+ const child = ctx.getChild(ix);
+ if (child.constructor?.name === 'IntegerArgumentContext') {
+ this.tryAppendCastToLong_IntArg(child);
+ }
+ this.visit(child);
+ }
+ }
+
+ // ─── Cast helpers ────────────────────────────────────────────────────────
+
+ private tryAppendCastToLong_IntArg(ctx: any): void {
+ if (ctx?.variable() != null) this.sb.push('(long) ');
+ }
+
+ private tryAppendCastToString_StringArg(ctx: any): void {
+ if (ctx?.variable() != null || ctx?.stringLiteral() != null) this.sb.push('(string) ');
+ }
+
+ private tryAppendCastToString_StringNullableLit(ctx: any): void {
+ if (ctx?.K_NULL != null && ctx.K_NULL() != null) this.sb.push('(string) ');
+ }
+
+ private tryAppendCastToString_StringNullableArg(ctx: any): void {
+ if (ctx?.variable() != null ||
+ (ctx?.stringNullableLiteral() != null && ctx.stringNullableLiteral()?.K_NULL != null && ctx.stringNullableLiteral().K_NULL() != null)) {
+ this.sb.push('(string) ');
+ }
+ }
+
+ private tryAppendCastToObject_GenericArg(ctx: any): void {
+ if (ctx?.variable() != null ||
+ (ctx?.genericLiteral() != null && ctx.genericLiteral()?.nullLiteral != null && ctx.genericLiteral().nullLiteral() != null)) {
+ this.sb.push('(object) ');
+ }
+ }
+
+ private tryAppendCastToObject_GenericLit(ctx: any): void {
+ if (ctx?.nullLiteral != null && ctx.nullLiteral() != null) this.sb.push('(object) ');
+ }
+
+ // ─── isCalledAsFirstStepInAnonymousTraversal ─────────────────────────────
+
+ private isCalledAsFirstStepInAnonymousTraversal(ctx: any): boolean {
+ // ctx = traversalMethod_fold_EmptyContext
+ // parent = traversalMethodContext → chainedTraversalContext → nestedTraversalContext
+ const parent = ctx.parent;
+ if (!parent) return false;
+ const parentParent = parent.parent; // ChainedTraversalContext
+ if (!parentParent) return false;
+ const parentParentParent = parentParent.parent; // should be NestedTraversalContext
+ if (parentParentParent?.constructor?.name !== 'NestedTraversalContext') return false;
+ // Check if ctx is the first step: parentParent.child(0).child(0) === ctx
+ const firstChild = parentParent.getChild(0);
+ const firstGrandchild = firstChild?.getChild(0);
+ return firstGrandchild === ctx;
+ }
+
+ // ─── Source spawn method overrides ──────────────────────────────────────
+
+ visitTraversalSourceSpawnMethod_inject(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalSourceSpawnMethod_io(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalSourceSpawnMethod_union(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalSourceSpawnMethod_call_empty(ctx: any): void { this.handleGenerics(ctx); }
+
+ visitTraversalSourceSpawnMethod_addV(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ for (let ix = 1; ix < ctx.getChildCount(); ix++) {
+ const child = ctx.getChild(ix);
+ if (child.constructor?.name === 'StringArgumentContext') this.tryAppendCastToString_StringArg(child);
+ this.visit(child);
+ }
+ }
+
+ visitTraversalSourceSpawnMethod_addE(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ for (let ix = 1; ix < ctx.getChildCount(); ix++) {
+ const child = ctx.getChild(ix);
+ if (child.constructor?.name === 'StringArgumentContext') this.tryAppendCastToString_StringArg(child);
+ this.visit(child);
+ }
+ }
+
+ visitTraversalSourceSpawnMethod_call_string(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>');
+ this.sb.push('((string) ');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_call_string_map(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>(');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(', (IDictionary<object, object>) ');
+ this.visit(ctx.genericMapArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_call_string_traversal(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>(');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(', (ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_call_string_map_traversal(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>(');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(', (IDictionary<object, object>) ');
+ this.visit(ctx.genericMapArgument());
+ this.sb.push(', (ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_mergeV_Map(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((IDictionary<object, object>) ');
+ this.visit(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_mergeV_Traversal(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_mergeE_Map(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((IDictionary<object, object>) ');
+ this.visit(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_mergeE_Traversal(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ // ─── Traversal method overrides — handleGenerics ─────────────────────────
+
+ visitTraversalMethod_asString_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_branch(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_cap(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_choose_Function(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_choose_Predicate_Traversal(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_choose_Predicate_Traversal_Traversal(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_choose_Traversal(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_choose_Traversal_Traversal(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_choose_Traversal_Traversal_Traversal(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_coalesce(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_constant(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_elementMap(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_flatMap(ctx: any): void { this.handleGenerics(ctx); }
+
+ visitTraversalMethod_fold_Empty(ctx: any): void {
+ if (this.isCalledAsFirstStepInAnonymousTraversal(ctx)) {
+ this.handleGenerics(ctx);
+ } else {
+ this.visitChildren(ctx); // base: just output Fold()
+ }
+ }
+
+ visitTraversalMethod_fold_Object_BiFunction(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_group_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_groupCount_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_index(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_length_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_local(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_lTrim_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_map(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_match(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_max_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_max_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_mean_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_mean_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_min_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_min_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_optional(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_profile_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_project(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_properties(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_propertyMap(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_replace_Scope_String_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_rTrim_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_sack_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_select_Column(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_select_Pop_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_select_Pop_String_String_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_select_Pop_Traversal(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_select_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_select_String_String_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_select_Traversal(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_split_Scope_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_substring_Scope_int(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_substring_Scope_int_int(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_sum_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_sum_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_tail_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_tail_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_toLower_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_toUpper_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_tree_Empty(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_trim_Scope(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_unfold(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_union(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_value(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_valueMap_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_valueMap_boolean_String(ctx: any): void { this.handleGenerics(ctx); }
+ visitTraversalMethod_values(ctx: any): void { this.handleGenerics(ctx); }
+
+ // ─── Traversal method overrides — handleLongArguments ────────────────────
+
+ visitTraversalMethod_limit_long(ctx: any): void { this.handleLongArguments(ctx); }
+ visitTraversalMethod_limit_Scope_long(ctx: any): void { this.handleLongArguments(ctx); }
+ visitTraversalMethod_range_long_long(ctx: any): void { this.handleLongArguments(ctx); }
+ visitTraversalMethod_range_Scope_long_long(ctx: any): void { this.handleLongArguments(ctx); }
+ visitTraversalMethod_skip_long(ctx: any): void { this.handleLongArguments(ctx); }
+ visitTraversalMethod_skip_Scope_long(ctx: any): void { this.handleLongArguments(ctx); }
+ visitTraversalMethod_tail_long(ctx: any): void { this.handleLongArguments(ctx); }
+ visitTraversalMethod_tail_Scope_long(ctx: any): void { this.handleLongArguments(ctx); }
+
+ // ─── addV / addE (string cast) ───────────────────────────────────────────
+
+ visitTraversalMethod_addV_String(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ for (let ix = 1; ix < ctx.getChildCount(); ix++) {
+ const child = ctx.getChild(ix);
+ if (child.constructor?.name === 'StringArgumentContext') this.tryAppendCastToString_StringArg(child);
+ this.visit(child);
+ }
+ }
+
+ visitTraversalMethod_addE_String(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ for (let ix = 1; ix < ctx.getChildCount(); ix++) {
+ const child = ctx.getChild(ix);
+ if (child.constructor?.name === 'StringArgumentContext') this.tryAppendCastToString_StringArg(child);
+ this.visit(child);
+ }
+ }
+
+ // ─── call variants ───────────────────────────────────────────────────────
+
+ visitTraversalMethod_call_string(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>((string) ');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_call_string_map(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>(');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(', (IDictionary<object, object>) ');
+ this.visit(ctx.genericMapArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_call_string_traversal(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>(');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(', (ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_call_string_map_traversal(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('<object>(');
+ this.visit(ctx.stringLiteral());
+ this.sb.push(', (IDictionary<object, object>) ');
+ this.visit(ctx.genericMapArgument());
+ this.sb.push(', (ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ // ─── has family ──────────────────────────────────────────────────────────
+
+ visitTraversalMethod_has_String_Object(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.tryAppendCastToString_StringNullableLit(ctx.stringNullableLiteral());
+ this.visit(ctx.stringNullableLiteral());
+ this.sb.push(', ');
+ this.tryAppendCastToObject_GenericArg(ctx.genericArgument());
+ this.visit(ctx.genericArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_has_String_P(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.tryAppendCastToString_StringNullableLit(ctx.stringNullableLiteral());
+ this.visit(ctx.stringNullableLiteral());
+ this.sb.push(', ');
+ this.visit(ctx.traversalPredicate());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_has_String_String_Object(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.tryAppendCastToString_StringNullableArg(ctx.stringNullableArgument());
+ this.visit(ctx.stringNullableArgument());
+ this.sb.push(', ');
+ this.tryAppendCastToString_StringNullableLit(ctx.stringNullableLiteral());
+ this.visit(ctx.stringNullableLiteral());
+ this.sb.push(', ');
+ this.tryAppendCastToObject_GenericArg(ctx.genericArgument());
+ this.visit(ctx.genericArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_has_String_String_P(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.tryAppendCastToString_StringNullableArg(ctx.stringNullableArgument());
+ this.visit(ctx.stringNullableArgument());
+ this.sb.push(', ');
+ this.tryAppendCastToString_StringNullableLit(ctx.stringNullableLiteral());
+ this.visit(ctx.stringNullableLiteral());
+ this.sb.push(', ');
+ this.visit(ctx.traversalPredicate());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_has_T_Object(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.visit(ctx.traversalT());
+ this.sb.push(', ');
+ this.tryAppendCastToObject_GenericArg(ctx.genericArgument());
+ this.visit(ctx.genericArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_has_T_P(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.visit(ctx.traversalT());
+ this.sb.push(', ');
+ this.visit(ctx.traversalPredicate());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_hasKey_P(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.visit(ctx.traversalPredicate());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_hasKey_String_String(ctx: any): void {
+ // single arg: add (string) cast; multiple args: no cast
+ if (ctx.stringNullableLiteralVarargs() == null || ctx.stringNullableLiteralVarargs().getChildCount() === 0) {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.tryAppendCastToString_StringNullableLit(ctx.stringNullableLiteral());
+ this.visit(ctx.stringNullableLiteral());
+ this.sb.push(')');
+ } else {
+ this.visitChildren(ctx);
+ }
+ }
+
+ visitTraversalMethod_hasValue_Object_Object(ctx: any): void {
+ // single arg: add (object) cast; multiple args: no cast
+ if (ctx.genericArgumentVarargs() == null || ctx.genericArgumentVarargs().getChildCount() === 0) {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.tryAppendCastToObject_GenericArg(ctx.genericArgument());
+ this.visit(ctx.genericArgument());
+ this.sb.push(')');
+ } else {
+ this.visitChildren(ctx);
+ }
+ }
+
+ visitTraversalMethod_hasValue_P(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.visit(ctx.traversalPredicate());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_hasLabel_P(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.visit(ctx.traversalPredicate());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_hasLabel_String_String(ctx: any): void {
+ const step = capitalize(ctx.getChild(0).getText());
+ if (ctx.stringNullableArgumentVarargs() == null || ctx.stringNullableArgumentVarargs().getChildCount() === 0) {
+ // single arg: add (string) cast if variable or null
+ this.sb.push(step);
+ this.sb.push('(');
+ this.tryAppendCastToString_StringNullableArg(ctx.stringNullableArgument());
+ this.visit(ctx.stringNullableArgument());
+ this.sb.push(')');
+ } else {
+ // multiple args
+ this.sb.push(step);
+ this.sb.push('(');
+ this.tryAppendCastToString_StringNullableArg(ctx.stringNullableArgument());
+ this.visit(ctx.stringNullableArgument());
+ if (ctx.stringNullableArgumentVarargs().getChildCount() > 0) this.sb.push(', ');
+ this.visit(ctx.stringNullableArgumentVarargs());
+ this.sb.push(')');
+ }
+ }
+
+ // ─── mergeV / mergeE ─────────────────────────────────────────────────────
+
+ visitTraversalMethod_mergeV_Map(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((IDictionary<object, object>) ');
+ this.visit(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_mergeV_Traversal(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_mergeE_Map(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((IDictionary<object, object>) ');
+ this.visit(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_mergeE_Traversal(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('((ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ // ─── option ─────────────────────────────────────────────────────────────
+
+ visitTraversalMethod_option_Merge_Map(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('(');
+ this.visit(ctx.traversalMerge());
+ this.sb.push(', (IDictionary<object, object>) ');
+ this.visit(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_option_Merge_Traversal(ctx: any): void {
+ this.visit(ctx.getChild(0));
+ this.sb.push('(');
+ this.visit(ctx.traversalMerge());
+ this.sb.push(', (ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_option_Object_Traversal(ctx: any): void {
+ // Only add (ITraversal) cast when the object is a traversalMerge
+ const argIsTraversalMerge = ctx.genericArgument()?.genericLiteral()?.traversalMerge != null &&
+ ctx.genericArgument().genericLiteral().traversalMerge() != null;
+ if (argIsTraversalMerge) {
+ this.visit(ctx.getChild(0));
+ this.sb.push('(');
+ this.visit(ctx.genericArgument());
+ this.sb.push(', (ITraversal) ');
+ this.visit(ctx.nestedTraversal());
+ this.sb.push(')');
+ } else {
+ this.visitChildren(ctx);
+ }
+ }
+
+ // ─── property ────────────────────────────────────────────────────────────
+
+ visitTraversalMethod_property_Cardinality_Object_Object_Object(ctx: any): void {
+ if (ctx.genericArgumentVarargs() == null || ctx.genericArgumentVarargs().getChildCount() === 0) {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.visit(ctx.traversalCardinality());
+ this.sb.push(', ');
+ this.tryAppendCastToObject_GenericLit(ctx.genericLiteral());
+ this.visit(ctx.genericLiteral());
+ this.sb.push(', ');
+ this.tryAppendCastToObject_GenericArg(ctx.genericArgument());
+ this.visit(ctx.genericArgument());
+ this.sb.push(')');
+ } else {
+ this.visitChildren(ctx);
+ }
+ }
+
+ // ─── conjoin ─────────────────────────────────────────────────────────────
+
+ visitTraversalMethod_conjoin_String(ctx: any): void {
+ this.sb.push(capitalize(ctx.getChild(0).getText()));
+ this.sb.push('(');
+ this.tryAppendCastToString_StringLit(ctx.stringLiteral());
+ this.visit(ctx.stringLiteral());
+ this.sb.push(')');
+ }
+
+ private tryAppendCastToString_StringLit(ctx: any): void {
+ if (ctx != null) this.sb.push('(string) ');
+ }
+}
+
+// ─── Helpers ─────────────────────────────────────────────────────────────────
+
+function capitalize(s: string): string {
+ if (!s) return s;
+ return s.charAt(0).toUpperCase() + s.slice(1);
+}
+
+/**
+ * Formats a datetime string the same way Java's OffsetDateTime.toString() does:
+ * - Truncates seconds if both seconds and milliseconds are 0
+ * - Uses 'Z' for UTC offset
+ */
+function formatDatetimeJavaStyle(s: string): string {
+ const d = new Date(s);
+ if (isNaN(d.getTime())) {
+ throw new TranslatorException(`Invalid datetime: ${s}`);
+ }
+ const year = d.getUTCFullYear().toString().padStart(4, '0');
+ const month = (d.getUTCMonth() + 1).toString().padStart(2, '0');
+ const day = d.getUTCDate().toString().padStart(2, '0');
+ const hours = d.getUTCHours().toString().padStart(2, '0');
+ const minutes = d.getUTCMinutes().toString().padStart(2, '0');
+ const seconds = d.getUTCSeconds();
+ const millis = d.getUTCMilliseconds();
+
+ let result = `${year}-${month}-${day}T${hours}:${minutes}`;
+ if (seconds !== 0 || millis !== 0) {
+ result += ':' + seconds.toString().padStart(2, '0');
+ if (millis !== 0) {
+ result += '.' + millis.toString().padStart(3, '0').replace(/0+$/, '');
+ }
+ }
+ result += 'Z';
+ return result;
+}
+
+class SymbolHelper {
+ private static readonly TO_CS_MAP: Record<string, string> = {
+ 'graphml': 'GraphML',
+ 'graphson': 'GraphSON',
+ 'bigdecimal': 'BigDecimal',
+ 'bigint': 'BigInt',
+ 'datetime': 'DateTime',
+ 'uuid': 'UUID',
+ 'vproperty': 'VProperty',
+ };
+
+ static toCSharp(symbol: string): string {
+ return SymbolHelper.TO_CS_MAP[symbol] ?? capitalize(symbol);
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GoTranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GoTranslateVisitor.ts
new file mode 100644
index 0000000000..a3806bca85
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GoTranslateVisitor.ts
@@ -0,0 +1,375 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Context parameters are typed as `any` because the generated grammar files
+// require accepting arbitrary context types at runtime.
+
+import TranslateVisitor from './TranslateVisitor.js';
+import { TranslatorException } from './TranslatorException.js';
+
+const GO_PACKAGE_NAME = 'gremlingo.';
+
+const STRATEGY_WITH_MAP_OPTS = new Set([
+ 'OptionsStrategy',
+ 'ReferenceElementStrategy', 'ComputerFinalizationStrategy', 'ProfileStrategy',
+ 'ComputerVerificationStrategy', 'StandardVerificationStrategy', 'VertexProgramRestrictionStrategy',
+ 'MessagePassingReductionStrategy',
+]);
+
+const STRATEGY_WITH_STRING_SLICE = new Set([
+ 'ReservedKeysVerificationStrategy', 'ProductiveByStrategy',
+]);
+
+/**
+ * Converts a Gremlin traversal string into a Go source code representation.
+ * Assumes use of the gremlingo, math, time, and uuid packages.
+ */
+export default class GoTranslateVisitor extends TranslateVisitor {
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ super(graphTraversalSourceName);
+ }
+
+ protected override processGremlinSymbol(step: string): string {
+ return SymbolHelper.toGo(step);
+ }
+
+ protected override getCardinalityFunctionClass(): string {
+ return 'CardinalityValue';
+ }
+
+ protected override appendExplicitNaming(txt: string, prefix: string): void {
+ this.sb.push(GO_PACKAGE_NAME);
+ super.appendExplicitNaming(txt, prefix);
+ }
+
+ protected override appendAnonymousSpawn(): void {
+ this.sb.push(GO_PACKAGE_NAME + 'T__.');
+ }
+
+ protected override visitP(ctx: any, pClass: string, methodName: string): void {
+ this.sb.push(GO_PACKAGE_NAME);
+ super.visitP(ctx, pClass, methodName);
+ }
+
+ visitTraversalGType(ctx: any): void {
+ const parts: string[] = ctx.getText().split('.');
+ this.sb.push(GO_PACKAGE_NAME);
+ this.sb.push(this.processGremlinSymbol(parts[0]));
+ this.sb.push('.');
+ this.sb.push(this.processGremlinSymbol(parts[1].toLowerCase()));
+ }
+
+ visitNanLiteral(_ctx: any): void {
+ this.sb.push('math.NaN()');
+ }
+
+ visitInfLiteral(ctx: any): void {
+ if (ctx.SignedInfLiteral() != null && ctx.SignedInfLiteral().getText() === '-Infinity') {
+ this.sb.push('math.Inf(-1)');
+ } else {
+ this.sb.push('math.Inf(1)');
+ }
+ }
+
+ visitNullLiteral(_ctx: any): void {
+ this.sb.push('nil');
+ }
+
+ visitStringNullableLiteral(ctx: any): void {
+ if (ctx.getText() === 'null') {
+ this.sb.push('nil');
+ } else {
+ const text = TranslateVisitor.removeFirstAndLastCharacters(ctx.getText());
+ this.handleStringLiteralText(text);
+ }
+ }
+
+ visitIntegerLiteral(ctx: any): void {
+ const integerLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = integerLiteral[integerLiteral.length - 1];
+ const num = integerLiteral.slice(0, -1);
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(integerLiteral);
+ return;
+ }
+
+ switch (lastChar) {
+ case 'b':
+ this.sb.push('int8(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 's':
+ this.sb.push('int16(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 'i':
+ this.sb.push('int32(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 'l':
+ this.sb.push('int64(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 'n':
+ this.sb.push(GO_PACKAGE_NAME + 'ParseBigInt("');
+ this.sb.push(num);
+ this.sb.push('")');
+ break;
+ default:
+ this.sb.push(integerLiteral);
+ }
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ if (ctx.infLiteral() != null) { this.visit(ctx.infLiteral()); return; }
+ if (ctx.nanLiteral() != null) { this.visit(ctx.nanLiteral()); return; }
+
+ const floatLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = floatLiteral[floatLiteral.length - 1];
+ const num = floatLiteral.slice(0, -1);
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(floatLiteral);
+ return;
+ }
+
+ switch (lastChar) {
+ case 'f':
+ this.sb.push('float32(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 'd':
+ this.sb.push(num);
+ break;
+ case 'm':
+ this.sb.push(GO_PACKAGE_NAME + 'ParseBigDecimal("');
+ this.sb.push(num);
+ this.sb.push('")');
+ break;
+ default:
+ this.sb.push(floatLiteral);
+ }
+ }
+
+ visitDateLiteral(ctx: any): void {
+ const dtString: string = ctx.getChild(2).getText();
+ const inner = TranslateVisitor.removeFirstAndLastCharacters(dtString);
+ const d = new Date(inner);
+ if (isNaN(d.getTime())) {
+ throw new TranslatorException(`Invalid datetime: ${inner}`);
+ }
+
+ const year = d.getUTCFullYear();
+ const month = d.getUTCMonth() + 1;
+ const day = d.getUTCDate();
+ const hours = d.getUTCHours();
+ const minutes = d.getUTCMinutes();
+ const seconds = d.getUTCSeconds();
+ const nanos = d.getUTCMilliseconds() * 1_000_000;
+ const totalSeconds = 0; // assume UTC when no offset specified
+ const zoneInfo = 'UTC+00:00';
+
+ this.sb.push(`time.Date(${year}, ${month}, ${day}, ${hours}, ${minutes}, ${seconds}, ${nanos}, time.FixedZone("${zoneInfo}", ${totalSeconds}))`);
+ }
+
+ visitGenericRangeLiteral(_ctx: any): void {
+ throw new TranslatorException('Go does not support range literals');
+ }
+
+ visitGenericSetLiteral(ctx: any): void {
+ this.sb.push(GO_PACKAGE_NAME + 'NewSimpleSet(');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push(')');
+ }
+
+ visitGenericCollectionLiteral(ctx: any): void {
+ this.sb.push('[]interface{}{');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push('}');
+ }
+
+ visitGenericMapLiteral(ctx: any): void {
+ this.sb.push('map[interface{}]interface{}{');
+ const entries: any[] = ctx.mapEntry();
+ for (let i = 0; i < entries.length; i++) {
+ this.visit(entries[i]);
+ if (i < entries.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push(' }');
+ }
+
+ visitMapEntry(ctx: any): void {
+ this.visit(ctx.mapKey());
+ this.sb.push(': ');
+ this.visit(ctx.genericLiteral());
+ }
+
+ visitMapKey(ctx: any): void {
+ const keyIndex = (ctx.LPAREN() != null && ctx.RPAREN() != null) ? 1 : 0;
+ this.visit(ctx.getChild(keyIndex));
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ if (ctx.stringLiteral() == null) {
+ this.sb.push('uuid.New()');
+ return;
+ }
+ this.sb.push('uuid.MustParse(');
+ this.visitStringLiteral(ctx.stringLiteral());
+ this.sb.push(')');
+ }
+
+ visitTraversalStrategy(ctx: any): void {
+ if (ctx.getChildCount() === 1) {
+ this.sb.push(GO_PACKAGE_NAME);
+ this.sb.push(ctx.getText());
+ this.sb.push('()');
+ return;
+ }
+
+ const firstText = ctx.getChild(0).getText();
+ const strategyName = firstText === 'new' ? ctx.getChild(1).getText() : firstText;
+
+ this.sb.push(GO_PACKAGE_NAME);
+ this.sb.push(strategyName);
+ this.sb.push('(');
+
+ if (!STRATEGY_WITH_MAP_OPTS.has(strategyName)) {
+ this.sb.push(GO_PACKAGE_NAME);
+ this.sb.push(strategyName);
+ this.sb.push('Config{');
+ }
+
+ const configs: any[] = ctx.configuration();
+ for (let ix = 0; ix < configs.length; ix++) {
+ this.visit(configs[ix]);
+ if (ix < configs.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+
+ if (strategyName !== 'OptionsStrategy') {
+ this.sb.push('}');
+ }
+ this.sb.push(')');
+ }
+
+ visitConfiguration(ctx: any): void {
+ const parent: string = ctx.parent.getText();
+ const parenIdx = parent.indexOf('(');
+ const rawName = parenIdx > -1 ? parent.substring(0, parenIdx) : parent;
+ const parentName = rawName.startsWith('new') ? rawName.substring(3) : rawName;
+
+ if (STRATEGY_WITH_MAP_OPTS.has(parentName)) {
+ this.sb.push('map[string]interface{}{"');
+ this.sb.push(ctx.getChild(0).getText());
+ this.sb.push('": ');
+ this.visit(ctx.getChild(2));
+ this.sb.push('}');
+ return;
+ }
+
+ const key: string = ctx.getChild(0).getText();
+ this.sb.push(SymbolHelper.toGo(key));
+ this.sb.push(': ');
+
+ const startIdx = this.sb.length;
+ this.visit(ctx.genericArgument());
+
+ if (STRATEGY_WITH_STRING_SLICE.has(parentName)) {
+ // Replace []interface{} with []string if present
+ const idx = this.sb.indexOf('[]interface{}', startIdx);
+ if (idx > -1) {
+ this.sb[idx] = '[]string';
+ }
+ }
+
+ if (key === 'readPartitions') {
+ // Replace []interface{}{items} with gremlingo.NewSimpleSet(items)
+ const added = this.sb.splice(startIdx);
+ const joined = added.join('');
+ const transformed = joined.replace(/^\[\]interface\{\}\{([\s\S]*)\}$/, GO_PACKAGE_NAME + 'NewSimpleSet($1)');
+ this.sb.push(transformed);
+ }
+ }
+
+ visitTraversalSourceSelfMethod_withoutStrategies(ctx: any): void {
+ this.sb.push('WithoutStrategies(');
+ this.sb.push(GO_PACKAGE_NAME);
+ this.sb.push(ctx.classType().getText());
+ this.sb.push('()');
+
+ if (ctx.classTypeList() != null && ctx.classTypeList().classTypeExpr() != null) {
+ for (const classTypeCtx of ctx.classTypeList().classTypeExpr().classType()) {
+ this.sb.push(', ');
+ this.sb.push(GO_PACKAGE_NAME);
+ this.sb.push(classTypeCtx.getText());
+ this.sb.push('()');
+ }
+ }
+
+ this.sb.push(')');
+ }
+}
+
+class SymbolHelper {
+ private static readonly TO_GO_MAP: Record<string, string> = {
+ 'OUT': 'Out',
+ 'IN': 'In',
+ 'BOTH': 'Both',
+ 'bigdecimal': 'BigDecimal',
+ 'bigint': 'BigInt',
+ 'datetime': 'DateTime',
+ 'uuid': 'UUID',
+ 'vproperty': 'VProperty',
+ 'WithOptions': GO_PACKAGE_NAME + 'WithOptions',
+ 'IO': GO_PACKAGE_NAME + 'IO',
+ '__': GO_PACKAGE_NAME + 'T__',
+ };
+
+ static toGo(symbol: string): string {
+ if (symbol in SymbolHelper.TO_GO_MAP) {
+ return SymbolHelper.TO_GO_MAP[symbol];
+ }
+ // Capitalize first letter (mirrors Java StringUtils.capitalize)
+ if (!symbol) return symbol;
+ return symbol.charAt(0).toUpperCase() + symbol.slice(1);
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GremlinTranslator.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GremlinTranslator.ts
new file mode 100644
index 0000000000..b3ddda56b2
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GremlinTranslator.ts
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { ATNSimulator, BaseErrorListener, CharStream, CommonTokenStream, PredictionMode, Recognizer, RecognitionException } from 'antlr4ng';
+import { GremlinLexer } from '../grammar/GremlinLexer.js';
+import { GremlinParser } from '../grammar/GremlinParser.js';
+import { Translation } from './Translation.js';
+import { TranslatorException } from './TranslatorException.js';
+import TranslateVisitor from './TranslateVisitor.js';
+import JavascriptTranslateVisitor from './JavascriptTranslateVisitor.js';
+import { Translator, TranslatorKey } from './Translator.js';
+
+/**
+ * Error listener that throws TranslatorException on syntax errors.
+ */
+class ThrowingErrorListener extends BaseErrorListener {
+ override syntaxError(
+ _recognizer: Recognizer<ATNSimulator>,
+ _offendingSymbol: unknown,
+ line: number,
+ column: number,
+ msg: string,
+ _e: RecognitionException | null,
+ ): void {
+ throw new TranslatorException(`Failed to interpret Gremlin query at line ${line}:${column} - ${msg}`);
+ }
+}
+
+const errorListener = new ThrowingErrorListener();
+
+/**
+ * Translates a Gremlin string into a source code representation using ANTLR.
+ * Mirrors the Java GremlinTranslator with SLL → LL fallback parsing.
+ */
+export class GremlinTranslator {
+
+ /**
+ * Translates a Gremlin query string. Defaults to JavaScript output.
+ *
+ * @param query The Gremlin traversal string to translate.
+ * @param graphTraversalSourceName Name of the traversal source variable (default: 'g').
+ * @param translatorOrVisitor A TranslatorKey (e.g. 'JAVASCRIPT'), a custom
+ * TranslateVisitor instance, or omit for the default JavaScript translator.
+ */
+ static translate(
+ query: string,
+ graphTraversalSourceName?: string,
+ translatorOrVisitor?: TranslatorKey | TranslateVisitor,
+ ): Translation {
+ const sourceName = graphTraversalSourceName ?? 'g';
+
+ let visitor: TranslateVisitor;
+ if (translatorOrVisitor == null) {
+ visitor = new JavascriptTranslateVisitor(sourceName);
+ } else if (typeof translatorOrVisitor === 'string') {
+ visitor = Translator[translatorOrVisitor](sourceName);
+ } else {
+ visitor = translatorOrVisitor;
+ }
+
+ const chars = CharStream.fromString(query);
+ const lexer = new GremlinLexer(chars);
+ lexer.removeErrorListeners();
+ lexer.addErrorListener(errorListener);
+
+ const tokens = new CommonTokenStream(lexer);
+ const parser = new GremlinParser(tokens);
+ // SLL mode is faster; fall back to LL on parse failure (mirrors Java impl)
+ parser.interpreter.predictionMode = PredictionMode.SLL;
+ parser.removeErrorListeners();
+ parser.addErrorListener(errorListener);
+
+ let queryContext: ReturnType<typeof parser.queryList>;
+ try {
+ queryContext = parser.queryList();
+ } catch (_ex) {
+ try {
+ tokens.seek(0);
+ lexer.reset();
+ parser.reset();
+ parser.interpreter.predictionMode = PredictionMode.LL;
+ queryContext = parser.queryList();
+ } catch (e) {
+ throw new TranslatorException(
+ `Failed to interpret Gremlin query: ${e instanceof Error ? e.message : String(e)}`
+ );
+ }
+ }
+
+ visitor.visit(queryContext);
+
+ return new Translation(query, visitor.getTranslated(), visitor.getParameters());
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GroovyTranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GroovyTranslateVisitor.ts
new file mode 100644
index 0000000000..d9f99f5a47
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/GroovyTranslateVisitor.ts
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Context parameters are typed as `any` because the generated grammar files
+// require accepting arbitrary context types at runtime.
+
+import TranslateVisitor from './TranslateVisitor.js';
+
+/**
+ * Converts a Gremlin traversal string into a Groovy source code representation.
+ * Mirrors the Java GroovyTranslateVisitor.
+ */
+export default class GroovyTranslateVisitor extends TranslateVisitor {
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ super(graphTraversalSourceName);
+ }
+
+ visitIntegerLiteral(ctx: any): void {
+ const integerLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = integerLiteral[integerLiteral.length - 1];
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(integerLiteral);
+ return;
+ }
+
+ const num = integerLiteral.slice(0, -1);
+ switch (lastChar) {
+ case 'b':
+ this.sb.push('(byte)');
+ this.sb.push(num);
+ break;
+ case 's':
+ this.sb.push('(short)');
+ this.sb.push(num);
+ break;
+ case 'n':
+ // Groovy BigInteger uses the 'g' suffix
+ this.sb.push(num);
+ this.sb.push('g');
+ break;
+ default:
+ // i and l suffixes and anything else kept as-is
+ this.sb.push(integerLiteral);
+ }
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ if (ctx.infLiteral() != null) { this.visit(ctx.infLiteral()); return; }
+ if (ctx.nanLiteral() != null) { this.visit(ctx.nanLiteral()); return; }
+
+ const floatLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = floatLiteral[floatLiteral.length - 1];
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(floatLiteral);
+ return;
+ }
+
+ const num = floatLiteral.slice(0, -1);
+ switch (lastChar) {
+ case 'f':
+ case 'd':
+ // keep f/d suffix as-is
+ this.sb.push(floatLiteral);
+ break;
+ case 'm':
+ // Groovy BigDecimal: if no decimal point use new BigDecimal(NL), else just the number
+ if (!floatLiteral.includes('.')) {
+ this.sb.push('new BigDecimal(');
+ this.sb.push(num);
+ this.sb.push('L)');
+ } else {
+ this.sb.push(num);
+ }
+ break;
+ default:
+ this.sb.push(floatLiteral);
+ }
+ }
+
+ visitInfLiteral(ctx: any): void {
+ if (ctx.SignedInfLiteral() != null && ctx.SignedInfLiteral().getText() === '-Infinity') {
+ this.sb.push('Double.NEGATIVE_INFINITY');
+ } else {
+ this.sb.push('Double.POSITIVE_INFINITY');
+ }
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ if (ctx.stringLiteral() == null) {
+ this.sb.push('UUID.randomUUID()');
+ return;
+ }
+ this.sb.push('UUID.fromString(');
+ this.sb.push(ctx.stringLiteral().getText());
+ this.sb.push(')');
+ }
+
+ visitNullLiteral(ctx: any): void {
+ if (ctx.parent?.constructor?.name === 'GenericMapNullableArgumentContext') {
+ this.sb.push('null as Map');
+ } else {
+ this.sb.push(ctx.getText());
+ }
+ }
+
+ visitGenericSetLiteral(ctx: any): void {
+ this.sb.push('[');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) this.sb.push(', ');
+ }
+ this.sb.push('] as Set');
+ }
+
+ visitStringLiteral(ctx: any): void {
+ // Preserve original quote style and escape Groovy GString interpolation
+ this.sb.push(ctx.getText().replace(/\$/g, '\\$'));
+ }
+
+ visitStringNullableLiteral(ctx: any): void {
+ if (ctx.getText() === 'null') {
+ this.sb.push('null');
+ } else {
+ // Preserve original quote style and escape Groovy GString interpolation
+ this.sb.push(ctx.getText().replace(/\$/g, '\\$'));
+ }
+ }
+
+ visitMapKey(ctx: any): void {
+ if (ctx.LPAREN() != null && ctx.RPAREN() != null) {
+ // Groovy map syntax: expression keys must be parenthesized — preserve the parens
+ this.sb.push('(');
+ this.visit(ctx.getChild(1));
+ this.sb.push(')');
+ } else {
+ this.visit(ctx.getChild(0));
+ }
+ }
+
+ visitNakedKey(ctx: any): void {
+ // Groovy map/config syntax uses unquoted identifier keys
+ this.sb.push(ctx.getText());
+ }
+
+ visitKeyword(ctx: any): void {
+ const keyword: string = ctx.getText();
+ const parentName = ctx.parent?.constructor?.name ?? '';
+ if (parentName === 'MapKeyContext' || parentName === 'ConfigurationContext') {
+ // Groovy uses unquoted keys
+ this.sb.push(keyword);
+ } else {
+ this.sb.push(keyword);
+ this.sb.push(' ');
+ }
+ }
+
+ visitTraversalStrategy(ctx: any): void {
+ if (ctx.getChildCount() === 1) {
+ // No-arg strategy: output name as-is (no .instance())
+ this.sb.push(ctx.getText());
+ } else {
+ // Ensure 'new' keyword is present
+ if (ctx.getChild(0).getText() !== 'new') {
+ this.sb.push('new ');
+ }
+ this.visitChildren(ctx);
+ }
+ }
+
+ visitTraversalSourceSpawnMethod_inject(ctx: any): void {
+ this.handleInject(ctx);
+ }
+
+ visitTraversalMethod_inject(ctx: any): void {
+ this.handleInject(ctx);
+ }
+
+ visitTraversalMethod_hasLabel_String_String(ctx: any): void {
+ if (ctx.getChildCount() > 4 && ctx.getChild(2).getText() === 'null') {
+ const varArgs = ctx.getChild(4);
+ this.sb.push(ctx.getChild(0).getText());
+ this.sb.push('((String) null, ');
+ for (let i = 0; i < varArgs.getChildCount(); i += 2) {
+ if (varArgs.getChild(i).getText() === 'null') {
+ this.sb.push('(String) null');
+ } else {
+ this.visit(varArgs.getChild(i));
+ }
+ if (i < varArgs.getChildCount() - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push(')');
+ return;
+ }
+ this.visitChildren(ctx);
+ }
+
+ visitTraversalMethod_option_Merge_Map(ctx: any): void {
+ this.sb.push('option(');
+ this.visit(ctx.traversalMerge());
+ this.sb.push(', ');
+ this.tryCastMapNullableArgument(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_mergeV_Map(ctx: any): void {
+ this.sb.push('mergeV(');
+ this.tryCastMapNullableArgument(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_mergeV_Map(ctx: any): void {
+ this.sb.push('mergeV(');
+ this.tryCastMapNullableArgument(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalMethod_mergeE_Map(ctx: any): void {
+ this.sb.push('mergeE(');
+ this.tryCastMapNullableArgument(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ visitTraversalSourceSpawnMethod_mergeE_Map(ctx: any): void {
+ this.sb.push('mergeE(');
+ this.tryCastMapNullableArgument(ctx.genericMapNullableArgument());
+ this.sb.push(')');
+ }
+
+ private tryCastMapNullableArgument(ctx: any): void {
+ const nullableLit = ctx?.genericMapNullableLiteral?.();
+ if (nullableLit != null && nullableLit?.nullLiteral?.() != null) {
+ this.sb.push('(Map) null');
+ } else {
+ this.visit(ctx);
+ }
+ }
+
+ /**
+ * Special handling for inject with second `null` argument like g.inject(1, null).
+ * inject() is ambiguous in Groovy with jdk extension inject(Object, Closure).
+ */
+ private handleInject(ctx: any): void {
+ if (ctx.getChildCount() > 3) {
+ const child2 = ctx.getChild(2);
+ if (child2?.constructor?.name === 'GenericLiteralVarargsContext') {
+ const varArgs = child2;
+ if (varArgs.getChildCount() === 1) {
+ const child0 = varArgs.getChild(0);
+ if (child0?.constructor?.name === 'GenericLiteralExprContext') {
+ const injectArgs = child0;
+ if (injectArgs.getChildCount() > 2 && injectArgs.getChild(2).getText() === 'null') {
+ this.sb.push(ctx.getChild(0).getText());
+ this.sb.push('(');
+ for (let i = 0; i < injectArgs.getChildCount(); i += 2) {
+ if (i === 2) {
+ this.sb.push('(Object) null');
+ } else {
+ this.visit(injectArgs.getChild(i));
+ }
+ if (i < injectArgs.getChildCount() - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push(')');
+ return;
+ }
+ }
+ }
+ }
+ }
+ this.visitChildren(ctx);
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/JavaTranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/JavaTranslateVisitor.ts
new file mode 100644
index 0000000000..b7cf670f3d
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/JavaTranslateVisitor.ts
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Context parameters are typed as `any` because the generated grammar files
+// require accepting arbitrary context types at runtime.
+
+import TranslateVisitor from './TranslateVisitor.js';
+import { TranslatorException } from './TranslatorException.js';
+
+/**
+ * Converts a Gremlin traversal string into a Java source code representation.
+ * Mirrors the Java JavaTranslateVisitor.
+ */
+export default class JavaTranslateVisitor extends TranslateVisitor {
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ super(graphTraversalSourceName);
+ }
+
+ visitTraversalStrategy(ctx: any): void {
+ if (ctx.getChildCount() === 1) {
+ this.sb.push(ctx.getText());
+ this.sb.push('.instance()');
+ return;
+ }
+
+ this.visit(ctx.classType());
+ this.sb.push('.build()');
+
+ const configs: any[] = ctx.configuration();
+ // mirrors Java: ctx.getChild(1) is "OptionsStrategy" only when form is `new OptionsStrategy(...)`
+ const isNewOptionsStrategy: boolean = configs.length > 0 &&
+ ctx.getChild(1)?.getText() === 'OptionsStrategy';
+
+ if (isNewOptionsStrategy) {
+ for (const cfg of configs) {
+ this.sb.push('.with("');
+ this.sb.push(cfg.getChild(0).getText());
+ this.sb.push('", ');
+ this.visit(cfg.getChild(2));
+ this.sb.push(')');
+ }
+ } else {
+ for (const cfg of configs) {
+ this.sb.push('.');
+ this.visit(cfg);
+ }
+ }
+
+ this.sb.push('.create()');
+ }
+
+ visitConfiguration(ctx: any): void {
+ this.sb.push(ctx.getChild(0).getText());
+ this.sb.push('(');
+ this.visit(ctx.getChild(2));
+ this.sb.push(')');
+ }
+
+ visitClassType(ctx: any): void {
+ const parentName = ctx.parent?.constructor?.name ?? '';
+ this.sb.push(ctx.getText());
+ if (parentName === 'TraversalSourceSelfMethod_withoutStrategiesContext' ||
+ parentName === 'ClassTypeExprContext') {
+ this.sb.push('.class');
+ }
+ }
+
+ visitGenericMapLiteral(ctx: any): void {
+ this.sb.push('new LinkedHashMap<Object, Object>() {{ ');
+ const entries: any[] = ctx.mapEntry();
+ for (let i = 0; i < entries.length; i++) {
+ this.visit(entries[i]);
+ if (i < entries.length - 1) this.sb.push(' ');
+ }
+ this.sb.push(' }}');
+ }
+
+ visitMapEntry(ctx: any): void {
+ this.sb.push('put(');
+ this.visit(ctx.mapKey());
+ this.sb.push(', ');
+ this.visit(ctx.genericLiteral());
+ this.sb.push(');');
+ }
+
+ visitMapKey(ctx: any): void {
+ const keyIndex = (ctx.LPAREN() != null && ctx.RPAREN() != null) ? 1 : 0;
+ this.visit(ctx.getChild(keyIndex));
+ }
+
+ visitDateLiteral(ctx: any): void {
+ const dtString: string = ctx.getChild(2).getText();
+ const inner = TranslateVisitor.removeFirstAndLastCharacters(dtString);
+ this.sb.push('OffsetDateTime.parse("');
+ this.sb.push(formatDatetimeJavaStyle(inner));
+ this.sb.push('")');
+ }
+
+ visitNanLiteral(_ctx: any): void {
+ this.sb.push('Double.NaN');
+ }
+
+ visitInfLiteral(ctx: any): void {
+ if (ctx.SignedInfLiteral() != null && ctx.SignedInfLiteral().getText() === '-Infinity') {
+ this.sb.push('Double.NEGATIVE_INFINITY');
+ } else {
+ this.sb.push('Double.POSITIVE_INFINITY');
+ }
+ }
+
+ visitIntegerLiteral(ctx: any): void {
+ const integerLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = integerLiteral[integerLiteral.length - 1];
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(integerLiteral);
+ return;
+ }
+
+ const num = integerLiteral.slice(0, -1);
+ switch (lastChar) {
+ case 'b':
+ this.sb.push('new Byte(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 's':
+ this.sb.push('new Short(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 'i':
+ this.sb.push(num);
+ break;
+ case 'l':
+ this.sb.push(integerLiteral); // keep the 'l' suffix
+ break;
+ case 'n':
+ this.sb.push('new BigInteger("');
+ this.sb.push(num);
+ this.sb.push('")');
+ break;
+ default:
+ this.sb.push(integerLiteral);
+ }
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ if (ctx.infLiteral() != null) { this.visit(ctx.infLiteral()); return; }
+ if (ctx.nanLiteral() != null) { this.visit(ctx.nanLiteral()); return; }
+
+ const floatLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = floatLiteral[floatLiteral.length - 1];
+
+ if (!/[a-z]/.test(lastChar)) {
+ this.sb.push(floatLiteral);
+ return;
+ }
+
+ const num = floatLiteral.slice(0, -1);
+ switch (lastChar) {
+ case 'f':
+ case 'd':
+ this.sb.push(floatLiteral); // keep f/d suffix
+ break;
+ case 'm':
+ this.sb.push('new BigDecimal("');
+ this.sb.push(num);
+ this.sb.push('")');
+ break;
+ default:
+ this.sb.push(floatLiteral);
+ }
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ if (ctx.stringLiteral() == null) {
+ this.sb.push('UUID.randomUUID()');
+ return;
+ }
+ this.sb.push('UUID.fromString(');
+ this.sb.push(ctx.stringLiteral().getText());
+ this.sb.push(')');
+ }
+
+ visitGenericRangeLiteral(_ctx: any): void {
+ throw new TranslatorException('Java does not support range literals');
+ }
+
+ visitGenericSetLiteral(ctx: any): void {
+ this.sb.push('new HashSet<Object>() {{ ');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.sb.push('add(');
+ this.visit(literals[i]);
+ this.sb.push(');');
+ if (i < literals.length - 1) this.sb.push(' ');
+ }
+ this.sb.push(' }}');
+ }
+
+ visitGenericCollectionLiteral(ctx: any): void {
+ this.sb.push('new ArrayList<Object>() {{ ');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.sb.push('add(');
+ this.visit(literals[i]);
+ this.sb.push(');');
+ if (i < literals.length - 1) this.sb.push(' ');
+ }
+ this.sb.push(' }}');
+ }
+}
+
+// ─── Helpers ─────────────────────────────────────────────────────────────────
+
+/**
+ * Formats a datetime string the same way Java's OffsetDateTime.toString() does:
+ * - Truncates seconds if both seconds and milliseconds are 0
+ * - Uses 'Z' for UTC offset
+ */
+function formatDatetimeJavaStyle(s: string): string {
+ const d = new Date(s);
+ if (isNaN(d.getTime())) {
+ throw new TranslatorException(`Invalid datetime: ${s}`);
+ }
+ const year = d.getUTCFullYear().toString().padStart(4, '0');
+ const month = (d.getUTCMonth() + 1).toString().padStart(2, '0');
+ const day = d.getUTCDate().toString().padStart(2, '0');
+ const hours = d.getUTCHours().toString().padStart(2, '0');
+ const minutes = d.getUTCMinutes().toString().padStart(2, '0');
+ const seconds = d.getUTCSeconds();
+ const millis = d.getUTCMilliseconds();
+
+ let result = `${year}-${month}-${day}T${hours}:${minutes}`;
+ if (seconds !== 0 || millis !== 0) {
+ result += ':' + seconds.toString().padStart(2, '0');
+ if (millis !== 0) {
+ result += '.' + millis.toString().padStart(3, '0').replace(/0+$/, '');
+ }
+ }
+ result += 'Z';
+ return result;
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/JavascriptTranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/JavascriptTranslateVisitor.ts
new file mode 100644
index 0000000000..e01fb5568b
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/JavascriptTranslateVisitor.ts
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Context parameters are typed as `any` because the generated grammar files
+// use @ts-nocheck (the standard antlr4 npm package doesn't fully re-export
+// its TypeScript types from the main module entry point).
+
+import TranslateVisitor from './TranslateVisitor.js';
+import { TranslatorException } from './TranslatorException.js';
+
+/**
+ * Converts a Gremlin traversal string into a JavaScript source code representation.
+ * Assumes use of https://www.npmjs.com/package/uuid library for UUID handling.
+ */
+export default class JavascriptTranslateVisitor extends TranslateVisitor {
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ super(graphTraversalSourceName);
+ }
+
+ protected override processGremlinSymbol(step: string): string {
+ return SymbolHelper.toJavascript(step);
+ }
+
+ protected override getCardinalityFunctionClass(): string {
+ return 'CardinalityValue';
+ }
+
+ visitTraversalStrategy(ctx: any): void {
+ this.sb.push('new ');
+
+ if (ctx.getChildCount() === 1) {
+ this.sb.push(ctx.getText());
+ this.sb.push('()');
+ } else {
+ const firstText = ctx.getChild(0).getText();
+ const className = firstText === 'new' ? ctx.getChild(1).getText() : firstText;
+ this.sb.push(className);
+ this.sb.push('({');
+
+ const configs: any[] = ctx.configuration();
+ for (let ix = 0; ix < configs.length; ix++) {
+ this.visit(configs[ix]);
+ if (ix < configs.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+
+ this.sb.push('})');
+ }
+ }
+
+ visitConfiguration(ctx: any): void {
+ const keyText: string = ctx.keyword() != null ? ctx.keyword().getText() : ctx.nakedKey().getText();
+ this.sb.push(SymbolHelper.toJavascript(keyText));
+ this.sb.push(': ');
+ this.visit(ctx.genericArgument());
+ }
+
+ visitTraversalGType(ctx: any): void {
+ const parts: string[] = ctx.getText().split('.');
+ this.sb.push(this.processGremlinSymbol(parts[0]));
+ this.sb.push('.');
+ this.sb.push(this.processGremlinSymbol(parts[1].toLowerCase()));
+ }
+
+ visitGenericMapLiteral(ctx: any): void {
+ this.sb.push('new Map([');
+ const entries: any[] = ctx.mapEntry();
+ for (let i = 0; i < entries.length; i++) {
+ this.visit(entries[i]);
+ if (i < entries.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push('])');
+ }
+
+ visitMapEntry(ctx: any): void {
+ this.sb.push('[');
+ this.visit(ctx.mapKey());
+ this.sb.push(', ');
+ this.visit(ctx.genericLiteral());
+ this.sb.push(']');
+ }
+
+ visitMapKey(ctx: any): void {
+ const keyIndex = (ctx.LPAREN() != null && ctx.RPAREN() != null) ? 1 : 0;
+ this.visit(ctx.getChild(keyIndex));
+ }
+
+ visitDateLiteral(ctx: any): void {
+ // child at index 2 is the string argument to datetime() — comes enclosed in quotes
+ const dtString: string = ctx.getChild(2).getText();
+ const inner = TranslateVisitor.removeFirstAndLastCharacters(dtString);
+ this.sb.push("new Date('");
+ this.sb.push(formatDatetimeJavaStyle(inner));
+ this.sb.push("')");
+ }
+
+ visitNanLiteral(_ctx: any): void {
+ this.sb.push('Number.NaN');
+ }
+
+ visitInfLiteral(ctx: any): void {
+ if (ctx.SignedInfLiteral() != null && ctx.SignedInfLiteral().getText() === '-Infinity') {
+ this.sb.push('Number.NEGATIVE_INFINITY');
+ } else {
+ this.sb.push('Number.POSITIVE_INFINITY');
+ }
+ }
+
+ visitIntegerLiteral(ctx: any): void {
+ const integerLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = integerLiteral[integerLiteral.length - 1];
+ if (/[a-z]/.test(lastChar)) {
+ this.sb.push(integerLiteral.slice(0, -1));
+ } else {
+ this.sb.push(integerLiteral);
+ }
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ if (ctx.infLiteral() != null) { this.visit(ctx.infLiteral()); return; }
+ if (ctx.nanLiteral() != null) { this.visit(ctx.nanLiteral()); return; }
+ const floatLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = floatLiteral[floatLiteral.length - 1];
+ if (/[a-z]/.test(lastChar)) {
+ this.sb.push(floatLiteral.slice(0, -1));
+ } else {
+ this.sb.push(floatLiteral);
+ }
+ }
+
+ visitGenericRangeLiteral(_ctx: any): void {
+ throw new TranslatorException('Javascript does not support range literals');
+ }
+
+ visitGenericSetLiteral(ctx: any): void {
+ this.sb.push('new Set([');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push('])');
+ }
+
+ visitGenericCollectionLiteral(ctx: any): void {
+ this.sb.push('[');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push(']');
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ if (ctx.stringLiteral() == null) {
+ this.sb.push('uuid.v4()');
+ return;
+ }
+ this.sb.push('uuid.parse(');
+ this.visitStringLiteral(ctx.stringLiteral());
+ this.sb.push(')');
+ }
+}
+
+/**
+ * Formats a datetime string the same way Java's OffsetDateTime.toString() does:
+ * - Truncates seconds if both seconds and milliseconds are 0
+ * - Uses 'Z' for UTC offset
+ * - Assumes UTC when no offset is specified
+ */
+function formatDatetimeJavaStyle(s: string): string {
+ const d = new Date(s);
+ if (isNaN(d.getTime())) {
+ throw new TranslatorException(`Invalid datetime: ${s}`);
+ }
+ const year = d.getUTCFullYear().toString().padStart(4, '0');
+ const month = (d.getUTCMonth() + 1).toString().padStart(2, '0');
+ const day = d.getUTCDate().toString().padStart(2, '0');
+ const hours = d.getUTCHours().toString().padStart(2, '0');
+ const minutes = d.getUTCMinutes().toString().padStart(2, '0');
+ const seconds = d.getUTCSeconds();
+ const millis = d.getUTCMilliseconds();
+
+ let result = `${year}-${month}-${day}T${hours}:${minutes}`;
+ if (seconds !== 0 || millis !== 0) {
+ result += ':' + seconds.toString().padStart(2, '0');
+ if (millis !== 0) {
+ result += '.' + millis.toString().padStart(3, '0').replace(/0+$/, '');
+ }
+ }
+ result += 'Z';
+ return result;
+}
+
+class SymbolHelper {
+ private static readonly TO_JS_MAP: Record<string, string> = {
+ 'from': 'from_',
+ 'in': 'in_',
+ 'with': 'with_',
+ 'bigdecimal': 'bigDecimal',
+ 'bigint': 'bigInt',
+ };
+
+ static toJavascript(symbol: string): string {
+ return SymbolHelper.TO_JS_MAP[symbol] ?? symbol;
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/PythonTranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/PythonTranslateVisitor.ts
new file mode 100644
index 0000000000..e74eb549c8
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/PythonTranslateVisitor.ts
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Context parameters are typed as `any` because the generated grammar files
+// require accepting arbitrary context types at runtime.
+
+import TranslateVisitor from './TranslateVisitor.js';
+import { TranslatorException } from './TranslatorException.js';
+
+/**
+ * Converts a Gremlin traversal string into a Python source code representation.
+ * Assumes use of the `uuid` and `datetime` standard library modules.
+ */
+export default class PythonTranslateVisitor extends TranslateVisitor {
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ super(graphTraversalSourceName);
+ }
+
+ protected override processGremlinSymbol(step: string): string {
+ return SymbolHelper.toPython(step);
+ }
+
+ protected override getCardinalityFunctionClass(): string {
+ return 'CardinalityValue';
+ }
+
+ protected override handleStringLiteralText(text: string): void {
+ this.sb.push("'");
+ this.sb.push(text);
+ this.sb.push("'");
+ }
+
+ visitBooleanLiteral(ctx: any): void {
+ const text: string = ctx.getText();
+ this.sb.push(text.charAt(0).toUpperCase() + text.slice(1));
+ }
+
+ visitNullLiteral(_ctx: any): void {
+ this.sb.push('None');
+ }
+
+ visitStringNullableLiteral(ctx: any): void {
+ if (ctx.getText() === 'null') {
+ this.sb.push('None');
+ } else {
+ const text = TranslateVisitor.removeFirstAndLastCharacters(ctx.getText());
+ this.handleStringLiteralText(text);
+ }
+ }
+
+ visitNanLiteral(_ctx: any): void {
+ this.sb.push("float('nan')");
+ }
+
+ visitInfLiteral(ctx: any): void {
+ if (ctx.SignedInfLiteral() != null && ctx.SignedInfLiteral().getText() === '-Infinity') {
+ this.sb.push("float('-inf')");
+ } else {
+ this.sb.push("float('inf')");
+ }
+ }
+
+ visitIntegerLiteral(ctx: any): void {
+ const integerLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = integerLiteral[integerLiteral.length - 1];
+
+ if (!/[a-z]/.test(lastChar)) {
+ // No type suffix — check if the value exceeds 32-bit signed integer range
+ const value = BigInt(integerLiteral);
+ if (value > BigInt(2147483647) || value < BigInt(-2147483648)) {
+ this.sb.push('long(');
+ this.sb.push(integerLiteral);
+ this.sb.push(')');
+ } else {
+ this.sb.push(integerLiteral);
+ }
+ return;
+ }
+
+ const num = integerLiteral.slice(0, -1);
+ switch (lastChar) {
+ case 'b':
+ case 's':
+ case 'i':
+ this.sb.push(num);
+ break;
+ case 'n':
+ this.sb.push('bigint(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ case 'l':
+ this.sb.push('long(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ default:
+ this.sb.push(integerLiteral);
+ break;
+ }
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ if (ctx.infLiteral() != null) { this.visit(ctx.infLiteral()); return; }
+ if (ctx.nanLiteral() != null) { this.visit(ctx.nanLiteral()); return; }
+
+ const floatLiteral: string = ctx.getText().toLowerCase();
+ const lastChar = floatLiteral[floatLiteral.length - 1];
+ const num = floatLiteral.slice(0, -1);
+
+ switch (lastChar) {
+ case 'f':
+ case 'd':
+ this.sb.push(num);
+ break;
+ case 'm':
+ this.sb.push('bigdecimal(');
+ this.sb.push(num);
+ this.sb.push(')');
+ break;
+ default:
+ this.sb.push(floatLiteral);
+ break;
+ }
+ }
+
+ visitDateLiteral(ctx: any): void {
+ const dtString: string = ctx.getChild(2).getText();
+ const inner = TranslateVisitor.removeFirstAndLastCharacters(dtString);
+ this.sb.push("datetime.datetime.fromisoformat('");
+ this.sb.push(formatDatetimePythonStyle(inner));
+ this.sb.push("')");
+ }
+
+ visitGenericRangeLiteral(_ctx: any): void {
+ throw new TranslatorException('Python does not support range literals');
+ }
+
+ visitGenericSetLiteral(ctx: any): void {
+ const literals: any[] = ctx.genericLiteral();
+ if (literals.length === 0) {
+ this.sb.push('set()');
+ return;
+ }
+ this.sb.push('{');
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push('}');
+ }
+
+ visitGenericCollectionLiteral(ctx: any): void {
+ this.sb.push('[');
+ const literals: any[] = ctx.genericLiteral();
+ for (let i = 0; i < literals.length; i++) {
+ this.visit(literals[i]);
+ if (i < literals.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push(']');
+ }
+
+ visitGenericMapLiteral(ctx: any): void {
+ this.sb.push('{ ');
+ const entries: any[] = ctx.mapEntry();
+ for (let i = 0; i < entries.length; i++) {
+ this.visit(entries[i]);
+ if (i < entries.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+ this.sb.push(' }');
+ }
+
+ visitMapEntry(ctx: any): void {
+ this.visit(ctx.mapKey());
+ this.sb.push(': ');
+ this.visit(ctx.genericLiteral());
+ }
+
+ visitMapKey(ctx: any): void {
+ const keyIndex = (ctx.LPAREN() != null && ctx.RPAREN() != null) ? 1 : 0;
+ this.visit(ctx.getChild(keyIndex));
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ if (ctx.stringLiteral() == null) {
+ this.sb.push('uuid.uuid4()');
+ return;
+ }
+ this.sb.push('uuid.UUID(');
+ this.visitStringLiteral(ctx.stringLiteral());
+ this.sb.push(')');
+ }
+
+ visitTraversalStrategy(ctx: any): void {
+ if (ctx.getChildCount() === 1) {
+ this.sb.push(ctx.getText());
+ this.sb.push('()');
+ } else {
+ const firstText = ctx.getChild(0).getText();
+ const className = firstText === 'new' ? ctx.getChild(1).getText() : firstText;
+ this.sb.push(className);
+ this.sb.push('(');
+
+ const configs: any[] = ctx.configuration();
+ for (let ix = 0; ix < configs.length; ix++) {
+ this.visit(configs[ix]);
+ if (ix < configs.length - 1) {
+ this.sb.push(', ');
+ }
+ }
+
+ this.sb.push(')');
+ }
+ }
+
+ visitConfiguration(ctx: any): void {
+ const keyText: string = ctx.keyword() != null ? ctx.keyword().getText() : ctx.nakedKey().getText();
+ this.sb.push(SymbolHelper.toPython(keyText));
+ this.sb.push('=');
+ this.visit(ctx.genericArgument());
+ }
+}
+
+/**
+ * Formats a datetime string for Python's datetime.fromisoformat():
+ * - Truncates seconds if both seconds and milliseconds are 0
+ * - Uses '+00:00' for UTC (Python < 3.11 does not support 'Z')
+ * - Assumes UTC when no offset is specified
+ */
+function formatDatetimePythonStyle(s: string): string {
+ const d = new Date(s);
+ if (isNaN(d.getTime())) {
+ throw new TranslatorException(`Invalid datetime: ${s}`);
+ }
+ const year = d.getUTCFullYear().toString().padStart(4, '0');
+ const month = (d.getUTCMonth() + 1).toString().padStart(2, '0');
+ const day = d.getUTCDate().toString().padStart(2, '0');
+ const hours = d.getUTCHours().toString().padStart(2, '0');
+ const minutes = d.getUTCMinutes().toString().padStart(2, '0');
+ const seconds = d.getUTCSeconds();
+ const millis = d.getUTCMilliseconds();
+
+ let result = `${year}-${month}-${day}T${hours}:${minutes}`;
+ if (seconds !== 0 || millis !== 0) {
+ result += ':' + seconds.toString().padStart(2, '0');
+ if (millis !== 0) {
+ result += '.' + millis.toString().padStart(3, '0').replace(/0+$/, '');
+ }
+ }
+ result += '+00:00';
+ return result;
+}
+
+class SymbolHelper {
+ private static readonly TO_PYTHON_MAP: Record<string, string> = {
+ 'global': 'global_',
+ 'all': 'all_',
+ 'and': 'and_',
+ 'any': 'any_',
+ 'as': 'as_',
+ 'filter': 'filter_',
+ 'format': 'format_',
+ 'from': 'from_',
+ 'id': 'id_',
+ 'in': 'in_',
+ 'is': 'is_',
+ 'list': 'list_',
+ 'max': 'max_',
+ 'min': 'min_',
+ 'or': 'or_',
+ 'not': 'not_',
+ 'range': 'range_',
+ 'set': 'set_',
+ 'sum': 'sum_',
+ 'with': 'with_',
+ };
+
+ static toPython(symbol: string): string {
+ return SymbolHelper.TO_PYTHON_MAP[symbol] ?? convertCamelCaseToSnakeCase(symbol);
+ }
+}
+
+function convertCamelCaseToSnakeCase(camelCase: string): string {
+ if (!camelCase) return camelCase;
+ // skip if this is a class/enum indicated by the first letter being upper case
+ if (camelCase.charAt(0) === camelCase.charAt(0).toUpperCase() && /[A-Z]/.test(camelCase.charAt(0))) {
+ return camelCase;
+ }
+ let result = '';
+ for (const c of camelCase) {
+ if (c >= 'A' && c <= 'Z') {
+ result += '_' + c.toLowerCase();
+ } else {
+ result += c;
+ }
+ }
+ return result;
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/TranslateVisitor.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/TranslateVisitor.ts
new file mode 100644
index 0000000000..dcf2b77aa1
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/TranslateVisitor.ts
@@ -0,0 +1,440 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { ErrorNode, TerminalNode } from 'antlr4ng';
+import { GremlinLexer } from '../grammar/GremlinLexer.js';
+
+/**
+ * Base visitor for translating Gremlin queries. Mirrors the Java TranslateVisitor.
+ * Makes no changes to input except:
+ * - Normalizes whitespace
+ * - Normalizes numeric suffixes to lower case
+ * - Makes anonymous traversals explicit with double underscore
+ * - Makes enums explicit with their proper name
+ */
+export default class TranslateVisitor {
+
+ protected readonly graphTraversalSourceName: string;
+ protected readonly sb: string[] = [];
+ protected readonly parameters: Set<string> = new Set();
+
+ constructor(graphTraversalSourceName: string = 'g') {
+ this.graphTraversalSourceName = graphTraversalSourceName;
+ }
+
+ getTranslated(): string {
+ return this.sb.join('');
+ }
+
+ getParameters(): ReadonlySet<string> {
+ return this.parameters;
+ }
+
+ protected processGremlinSymbol(step: string): string {
+ return step;
+ }
+
+ protected appendArgumentSeparator(): void {
+ this.sb.push(', ');
+ }
+
+ protected appendStepSeparator(): void {
+ this.sb.push('.');
+ }
+
+ protected appendStepOpen(): void {
+ this.sb.push('(');
+ }
+
+ protected appendStepClose(): void {
+ this.sb.push(')');
+ }
+
+ protected appendAnonymousSpawn(): void {
+ this.sb.push('__.');
+ }
+
+ visit(tree: any): void {
+ if (tree == null) return;
+
+ // antlr-ng does not generate accept() overrides per context class —
+ // ParserRuleContext.accept() always calls visitChildren, never dispatching to
+ // the specific visitXxx method. We perform the dispatch ourselves here by
+ // mapping the context class name (e.g. StringLiteralContext) to the
+ // corresponding visitor method (e.g. visitStringLiteral).
+ const className: string = tree?.constructor?.name ?? '';
+ if (className.endsWith('Context')) {
+ const methodName = 'visit' + className.slice(0, -'Context'.length);
+ const method = (this as any)[methodName];
+ if (typeof method === 'function') {
+ method.call(this, tree);
+ return;
+ }
+ }
+
+ // No specific visitor method found — fall through to accept() which calls
+ // visitChildren for rule contexts, visitTerminal for terminals.
+ (tree as any).accept(this);
+ }
+
+ visitChildren(node: any): void {
+ const n = node.getChildCount();
+ for (let i = 0; i < n; i++) {
+ this.visit(node.getChild(i));
+ }
+ }
+
+ protected getCardinalityFunctionClass(): string {
+ return 'Cardinality';
+ }
+
+ protected static removeFirstAndLastCharacters(text: string): string {
+ return text != null && text.length > 0 ? text.substring(1, text.length - 1) : '';
+ }
+
+ protected handleStringLiteralText(text: string): void {
+ this.sb.push('"');
+ this.sb.push(text);
+ this.sb.push('"');
+ }
+
+ protected appendExplicitNaming(txt: string, prefix: string): void {
+ if (!txt.startsWith(prefix + '.')) {
+ this.sb.push(this.processGremlinSymbol(prefix));
+ this.sb.push('.');
+ this.sb.push(this.processGremlinSymbol(txt));
+ } else {
+ const parts = txt.split('.');
+ this.sb.push(this.processGremlinSymbol(parts[0]));
+ this.sb.push('.');
+ this.sb.push(this.processGremlinSymbol(parts[1]));
+ }
+ }
+
+ visitTerminal(node: TerminalNode): void {
+ // skip EOF node
+ if (node == null || node.getSymbol().type === -1) return;
+
+ // TRAVERSAL_ROOT is the traversal source token (e.g. 'g') — always output as-is,
+ // never subject to processGremlinSymbol (which may capitalize it in some dialects).
+ if (node.getSymbol().type === GremlinLexer.TRAVERSAL_ROOT) {
+ this.sb.push(this.graphTraversalSourceName);
+ return;
+ }
+
+ const terminal = node.getSymbol().text ?? '';
+ switch (terminal) {
+ case '(':
+ this.appendStepOpen();
+ break;
+ case ')':
+ this.appendStepClose();
+ break;
+ case ',':
+ this.appendArgumentSeparator();
+ break;
+ case '.':
+ this.appendStepSeparator();
+ break;
+ case 'new':
+ this.sb.push('new');
+ if (!(node.parent?.constructor?.name === 'MapKeyContext')) {
+ this.sb.push(' ');
+ }
+ break;
+ default:
+ this.sb.push(this.processGremlinSymbol(terminal));
+ }
+ }
+
+ visitErrorNode(_node: ErrorNode): void {
+ // no-op
+ }
+
+ visitTraversalSource(ctx: any): void {
+ this.sb.push(this.graphTraversalSourceName);
+ // child counts more than 1 means there is a step separator and a traversal source method
+ if (ctx.getChildCount() > 1) {
+ if (ctx.getChild(0).getChildCount() > 1) {
+ this.appendStepSeparator();
+ this.visitTraversalSourceSelfMethod(ctx.getChild(0).getChild(2));
+ }
+ this.appendStepSeparator();
+ this.visitTraversalSourceSelfMethod(ctx.getChild(2));
+ }
+ }
+
+ visitTraversalSourceSelfMethod(ctx: any): void {
+ this.visitChildren(ctx);
+ }
+
+ visitNestedTraversal(ctx: any): void {
+ if (ctx.ANON_TRAVERSAL_ROOT() == null) {
+ this.appendAnonymousSpawn();
+ }
+ this.visitChildren(ctx);
+ }
+
+ visitTraversalScope(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Scope');
+ }
+
+ visitTraversalT(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'T');
+ }
+
+ visitTraversalTShort(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'T');
+ }
+
+ visitTraversalTLong(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'T');
+ }
+
+ visitTraversalMerge(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Merge');
+ }
+
+ visitTraversalOrder(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Order');
+ }
+
+ visitTraversalBarrier(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Barrier');
+ }
+
+ visitTraversalDirection(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Direction');
+ }
+
+ visitTraversalDirectionShort(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Direction');
+ }
+
+ visitTraversalDirectionLong(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Direction');
+ }
+
+ visitTraversalCardinality(ctx: any): void {
+ if (ctx.LPAREN() != null && ctx.RPAREN() != null) {
+ const idx = ctx.K_CARDINALITY() != null ? 2 : 0;
+ const txt = ctx.getChild(idx).getText();
+ this.appendExplicitNaming(txt, this.getCardinalityFunctionClass());
+ this.appendStepOpen();
+ this.visit(ctx.genericLiteral());
+ this.appendStepClose();
+ } else {
+ this.appendExplicitNaming(ctx.getText(), 'Cardinality');
+ }
+ }
+
+ visitTraversalColumn(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Column');
+ }
+
+ visitTraversalPop(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Pop');
+ }
+
+ visitTraversalOperator(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Operator');
+ }
+
+ visitTraversalPick(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'Pick');
+ }
+
+ visitTraversalDT(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'DT');
+ }
+
+ visitTraversalGType(ctx: any): void {
+ this.appendExplicitNaming(ctx.getText(), 'GType');
+ }
+
+ visitTraversalPredicate(ctx: any): void {
+ switch (ctx.getChildCount()) {
+ case 1:
+ this.visit(ctx.getChild(0));
+ break;
+ case 5:
+ // handle negate of P
+ this.visit(ctx.getChild(0));
+ this.sb.push('.');
+ this.sb.push(this.processGremlinSymbol('negate'));
+ this.sb.push('()');
+ break;
+ case 6:
+ // handle and/or predicates
+ this.visit(ctx.getChild(0));
+ this.sb.push('.');
+ this.sb.push(this.processGremlinSymbol(ctx.getChild(2).getText()));
+ this.sb.push('(');
+ this.visit(ctx.getChild(4));
+ this.sb.push(')');
+ break;
+ }
+ }
+
+ protected visitP(ctx: any, pClass: string, methodName: string): void {
+ this.sb.push(pClass);
+ this.appendStepSeparator();
+ this.sb.push(this.processGremlinSymbol(methodName));
+ this.appendStepOpen();
+
+ const children: any[] = [];
+ for (let i = 0; i < ctx.getChildCount(); i++) {
+ const child = ctx.getChild(i);
+ const name = child.constructor?.name ?? '';
+ if (name === 'GenericArgumentContext' ||
+ name === 'GenericArgumentVarargsContext' ||
+ name === 'StringArgumentContext' ||
+ name === 'StringLiteralContext' ||
+ name === 'TraversalGTypeContext' ||
+ name === 'TraversalPredicateContext') {
+ children.push(child);
+ }
+ }
+
+ for (let ix = 0; ix < children.length; ix++) {
+ this.visit(children[ix]);
+ if (ix < children.length - 1) {
+ this.appendArgumentSeparator();
+ }
+ }
+
+ this.appendStepClose();
+ }
+
+ visitTraversalPredicate_eq(ctx: any): void { this.visitP(ctx, 'P', 'eq'); }
+ visitTraversalPredicate_neq(ctx: any): void { this.visitP(ctx, 'P', 'neq'); }
+ visitTraversalPredicate_lt(ctx: any): void { this.visitP(ctx, 'P', 'lt'); }
+ visitTraversalPredicate_lte(ctx: any): void { this.visitP(ctx, 'P', 'lte'); }
+ visitTraversalPredicate_gt(ctx: any): void { this.visitP(ctx, 'P', 'gt'); }
+ visitTraversalPredicate_gte(ctx: any): void { this.visitP(ctx, 'P', 'gte'); }
+ visitTraversalPredicate_inside(ctx: any): void { this.visitP(ctx, 'P', 'inside'); }
+ visitTraversalPredicate_outside(ctx: any): void { this.visitP(ctx, 'P', 'outside'); }
+ visitTraversalPredicate_between(ctx: any): void { this.visitP(ctx, 'P', 'between'); }
+ visitTraversalPredicate_within(ctx: any): void { this.visitP(ctx, 'P', 'within'); }
+ visitTraversalPredicate_without(ctx: any): void { this.visitP(ctx, 'P', 'without'); }
+ visitTraversalPredicate_typeOf(ctx: any): void { this.visitP(ctx, 'P', 'typeOf'); }
+ visitTraversalPredicate_not(ctx: any): void { this.visitP(ctx, 'P', 'not'); }
+ visitTraversalPredicate_containing(ctx: any): void { this.visitP(ctx, 'TextP', 'containing'); }
+ visitTraversalPredicate_notContaining(ctx: any): void { this.visitP(ctx, 'TextP', 'notContaining'); }
+ visitTraversalPredicate_startingWith(ctx: any): void { this.visitP(ctx, 'TextP', 'startingWith'); }
+ visitTraversalPredicate_notStartingWith(ctx: any): void { this.visitP(ctx, 'TextP', 'notStartingWith'); }
+ visitTraversalPredicate_endingWith(ctx: any): void { this.visitP(ctx, 'TextP', 'endingWith'); }
+ visitTraversalPredicate_notEndingWith(ctx: any): void { this.visitP(ctx, 'TextP', 'notEndingWith'); }
+ visitTraversalPredicate_regex(ctx: any): void { this.visitP(ctx, 'TextP', 'regex'); }
+ visitTraversalPredicate_notRegex(ctx: any): void { this.visitP(ctx, 'TextP', 'notRegex'); }
+
+ visitBooleanArgument(ctx: any): void {
+ if (ctx.booleanLiteral() != null) {
+ this.visitBooleanLiteral(ctx.booleanLiteral());
+ } else {
+ this.visitVariable(ctx.variable());
+ }
+ }
+
+ visitGenericArgument(ctx: any): void {
+ if (ctx.genericLiteral() != null) {
+ this.visitGenericLiteral(ctx.genericLiteral());
+ } else {
+ this.visitVariable(ctx.variable());
+ }
+ }
+
+ visitGenericLiteral(ctx: any): void {
+ this.visitChildren(ctx);
+ }
+
+ visitIntegerLiteral(ctx: any): void {
+ this.sb.push(ctx.getText().toLowerCase());
+ }
+
+ visitFloatLiteral(ctx: any): void {
+ if (ctx.infLiteral() != null) { this.visit(ctx.infLiteral()); return; }
+ if (ctx.nanLiteral() != null) { this.visit(ctx.nanLiteral()); return; }
+ this.sb.push(ctx.getText().toLowerCase());
+ }
+
+ visitBooleanLiteral(ctx: any): void {
+ this.sb.push(ctx.getText());
+ }
+
+ visitNullLiteral(ctx: any): void {
+ this.sb.push(ctx.getText());
+ }
+
+ visitNanLiteral(ctx: any): void {
+ this.sb.push(ctx.getText());
+ }
+
+ visitInfLiteral(ctx: any): void {
+ this.sb.push(ctx.getText());
+ }
+
+ visitUuidLiteral(ctx: any): void {
+ this.sb.push(ctx.getText());
+ }
+
+ visitStringLiteral(ctx: any): void {
+ const text = TranslateVisitor.removeFirstAndLastCharacters(ctx.getText());
+ this.handleStringLiteralText(text);
+ }
+
+ visitStringNullableLiteral(ctx: any): void {
+ if (ctx.getText() === 'null') {
+ this.sb.push('null');
+ } else {
+ const text = TranslateVisitor.removeFirstAndLastCharacters(ctx.getText());
+ this.handleStringLiteralText(text);
+ }
+ }
+
+ visitNakedKey(ctx: any): void {
+ this.handleStringLiteralText(ctx.getText());
+ }
+
+ visitVariable(ctx: any): void {
+ const varName: string = ctx.getText();
+ this.sb.push(varName);
+ this.parameters.add(varName);
+ }
+
+ visitKeyword(ctx: any): void {
+ const keyword: string = ctx.getText();
+ if (ctx.parent?.constructor?.name === 'MapKeyContext' ||
+ ctx.parent?.constructor?.name === 'ConfigurationContext') {
+ this.handleStringLiteralText(keyword);
+ } else {
+ this.sb.push(keyword);
+ this.sb.push(' ');
+ }
+ }
+
+ visitMapKey(ctx: any): void {
+ const keyIndex = (ctx.LPAREN() != null && ctx.RPAREN() != null) ? 1 : 0;
+ this.visit(ctx.getChild(keyIndex));
+ }
+
+ visitMapEntry(ctx: any): void {
+ this.visitChildren(ctx);
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/Translation.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/Translation.ts
new file mode 100644
index 0000000000..f73469a233
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/Translation.ts
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Holds the result of a Gremlin translation.
+ */
+export class Translation {
+ constructor(
+ readonly original: string,
+ readonly translated: string,
+ readonly parameters: ReadonlySet<string>,
+ ) {}
+
+ getOriginal(): string {
+ return this.original;
+ }
+
+ getTranslated(): string {
+ return this.translated;
+ }
+
+ getParameters(): ReadonlySet<string> {
+ return this.parameters;
+ }
+
+ toString(): string {
+ return this.translated;
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/Translator.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/Translator.ts
new file mode 100644
index 0000000000..bcc66204cb
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/Translator.ts
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import TranslateVisitor from './TranslateVisitor.js';
+import JavascriptTranslateVisitor from './JavascriptTranslateVisitor.js';
+import PythonTranslateVisitor from './PythonTranslateVisitor.js';
+import GoTranslateVisitor from './GoTranslateVisitor.js';
+import DotNetTranslateVisitor from './DotNetTranslateVisitor.js';
+import JavaTranslateVisitor from './JavaTranslateVisitor.js';
+import GroovyTranslateVisitor from './GroovyTranslateVisitor.js';
+import AnonymizedTranslateVisitor from './AnonymizedTranslateVisitor.js';
+
+export type TranslatorFactory = (sourceName: string) => TranslateVisitor;
+
+/**
+ * Extensible registry of translator factories. New languages are added here
+ * without modifying any other file.
+ */
+export const Translator = {
+ CANONICAL: (sourceName: string) => new TranslateVisitor(sourceName),
+ JAVASCRIPT: (sourceName: string) => new JavascriptTranslateVisitor(sourceName),
+ PYTHON: (sourceName: string) => new PythonTranslateVisitor(sourceName),
+ GO: (sourceName: string) => new GoTranslateVisitor(sourceName),
+ DOTNET: (sourceName: string) => new DotNetTranslateVisitor(sourceName),
+ JAVA: (sourceName: string) => new JavaTranslateVisitor(sourceName),
+ GROOVY: (sourceName: string) => new GroovyTranslateVisitor(sourceName),
+ ANONYMIZED: (sourceName: string) => new AnonymizedTranslateVisitor(sourceName),
+} satisfies Record<string, TranslatorFactory>;
+
+export type TranslatorKey = keyof typeof Translator;
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/TranslatorException.ts b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/TranslatorException.ts
new file mode 100644
index 0000000000..c3da691c1b
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/language/translator/TranslatorException.ts
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Thrown when a Gremlin string cannot be translated to the target language.
+ */
+export class TranslatorException extends Error {
+ constructor(message: string) {
+ super(message);
+ this.name = 'TranslatorException';
+ }
+}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/buffer b/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/buffer
deleted file mode 100644
index 08293a476e..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/buffer
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Feross Aboukhadijeh, and other contributors.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/eventemitter3 b/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/eventemitter3
deleted file mode 100644
index bd02dacf38..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/eventemitter3
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Arnout Kazemier
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/readable-stream b/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/readable-stream
deleted file mode 100644
index 5fcbe0192f..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/readable-stream
+++ /dev/null
@@ -1,47 +0,0 @@
-Node.js is licensed for use as follows:
-
-"""
-Copyright Node.js contributors. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
-"""
-
-This license applies to parts of Node.js originating from the
-https://github.com/joyent/node repository:
-
-"""
-Copyright Joyent, Inc. and other Node contributors. All rights reserved.
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE.
-"""
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/uuid b/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/uuid
deleted file mode 100644
index 0bc895db2b..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/uuid
+++ /dev/null
@@ -1,9 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2010-2020 Robert Kieffer and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/ws b/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/ws
deleted file mode 100644
index 4e10ec2b8b..0000000000
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/licenses/ws
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2011 Einar Otto Stangvik <ei...@gmail.com>
-Copyright (c) 2013 Arnout Kazemier and contributors
-Copyright (c) 2016 Luigi Pinca and contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json
index b53cd1f839..7529cde241 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package-lock.json
@@ -7,8 +7,10 @@
"": {
"name": "gremlin",
"version": "4.0.0-alpha1",
+ "hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
+ "antlr4ng": "~3.0.16",
"buffer": "^6.0.3",
"eventemitter3": "^5.0.1",
"readable-stream": "^4.5.2",
@@ -18,11 +20,12 @@
"devDependencies": {
"@cucumber/cucumber": "~12.7.0",
"@eslint/js": "^9.16.0",
- "@knighted/duel": "^1.0.7",
+ "@knighted/duel": "^4.0.2",
"@tsconfig/node18": "^18.2.2",
"@types/readable-stream": "^4.0.10",
"@types/uuid": "^9.0.8",
"@types/ws": "^8.5.10",
+ "antlr-ng": "^1.0.10",
"chai": "~4.5.0",
"chai-string": "~1.5.0",
"colors": "1.4.0",
@@ -56,31 +59,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/generator": {
- "version": "7.29.1",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
- "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.29.0",
- "@babel/types": "^7.29.0",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-globals": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
- "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
@@ -114,38 +92,6 @@
"node": ">=6.0.0"
}
},
- "node_modules/@babel/template": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
- "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.28.6",
- "@babel/parser": "^7.28.6",
- "@babel/types": "^7.28.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
- "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0",
- "debug": "^4.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/types": {
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
@@ -402,6 +348,37 @@
"integrity": "sha512-bvHjcRFZ+J1TqIa9eFNO1wGHqwx4V9ZKV3hYgkuK/VahHx73uiP4rKV3JVrvWSMrwrFvJG6C8aEwnCWSvbyFdQ==",
"dev": true
},
+ "node_modules/@emnapi/core": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
+ "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.1.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
+ "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
+ "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@epic-web/invariant": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
@@ -764,180 +741,395 @@
}
},
"node_modules/@knighted/duel": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@knighted/duel/-/duel-1.0.8.tgz",
- "integrity": "sha512-qOKDR0mbtH8tL6dgbX8ks8udBytF67TlD3k1QUO/Chj0NX/qXBlrWg7ox33IFwYJP7PDSHd6QjWNG2lYLlN4Rg==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@knighted/duel/-/duel-4.0.2.tgz",
+ "integrity": "sha512-VnMWT2JZqSf3Xf1j9blZdbteJOxme+FEJF7dH/cW8gZLUDfBrsc0ZF6VZfb5Rhk4EbuaUP87qchnMjfGhuiIeQ==",
"dev": true,
"dependencies": {
- "@knighted/specifier": "^1.0.1",
- "find-up": "^6.3.0",
- "glob": "^10.3.3",
- "jsonc-parser": "^3.2.0",
- "read-package-up": "^11.0.0"
+ "@jridgewell/gen-mapping": "^0.3.13",
+ "@jridgewell/trace-mapping": "^0.3.31",
+ "@knighted/module": "^1.5.2",
+ "find-up": "^8.0.0",
+ "get-tsconfig": "^4.13.0",
+ "magic-string": "^0.30.21",
+ "read-package-up": "^12.0.0"
},
"bin": {
"duel": "dist/esm/duel.js"
},
"engines": {
- "node": ">=16.19.0"
+ "node": ">=22.21.1 <23 || >=24 <25"
},
"peerDependencies": {
- "typescript": ">=4.0.0 || >=4.9.0-dev || >=5.3.0-dev || >=5.4.0-dev || >=5.5.0-dev || next"
+ "typescript": ">=5.5.0 <6",
+ "typescript-next": "npm:typescript@next"
+ },
+ "peerDependenciesMeta": {
+ "typescript-next": {
+ "optional": true
+ }
}
},
- "node_modules/@knighted/duel/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "node_modules/@knighted/module": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@knighted/module/-/module-1.5.2.tgz",
+ "integrity": "sha512-FVvb4/fViJfaoLEmn81TGirmR/l36gQwiEEJ3SCz9FoD8MzTgYeFgA5oToAfTcFSxlZ9AEbukJyDh1KUz8X1HA==",
"dev": true,
"dependencies": {
- "balanced-match": "^1.0.0"
+ "magic-string": "^0.30.21",
+ "oxc-parser": "^0.116.0",
+ "periscopic": "^4.0.2"
+ },
+ "bin": {
+ "dub": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=22.21.1 <23 || >=24 <25"
}
},
- "node_modules/@knighted/duel/node_modules/glob": {
- "version": "10.5.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
- "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz",
+ "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==",
"dev": true,
+ "optional": true,
"dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^3.1.2",
- "minimatch": "^9.0.4",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^1.11.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1",
+ "@tybys/wasm-util": "^0.10.1"
},
"funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
}
},
- "node_modules/@knighted/duel/node_modules/hosted-git-info": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
- "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
+ "node_modules/@oxc-parser/binding-android-arm-eabi": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.116.0.tgz",
+ "integrity": "sha512-AOET7YIOU3+ANO/3xQeRVGN5Xx6+JGXaIwlqkcHSfxJ/zzw2B6jb0YaLhX45SeRluKVTU8rka4N/tHtNoJjoCg==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "dependencies": {
- "lru-cache": "^10.0.1"
- },
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
- "node": "^16.14.0 || >=18.0.0"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@knighted/duel/node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "dev": true
+ "node_modules/@oxc-parser/binding-android-arm64": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.116.0.tgz",
+ "integrity": "sha512-yh0Zvth5cQ6XZkP3QF9MDrXf695zr5XxXq/wBQqpZb0uAgI9wpr98/Hx2RZITMfnNjkIq2VcyU44o3A0bdEmlQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
},
- "node_modules/@knighted/duel/node_modules/minimatch": {
- "version": "9.0.9",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
- "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "node_modules/@oxc-parser/binding-darwin-arm64": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.116.0.tgz",
+ "integrity": "sha512-plcTd/Jska55dToZz6XdRBPRVsj+asjD8QCpQFvt3Wj8pY+10D1pE53Mei3POAS/wSRSy7HiQ2twrm7H2A0CjA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "dependencies": {
- "brace-expansion": "^2.0.2"
- },
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@knighted/duel/node_modules/normalize-package-data": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz",
- "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==",
+ "node_modules/@oxc-parser/binding-darwin-x64": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.116.0.tgz",
+ "integrity": "sha512-ahqcF3e3x5Z2ZepzXpZ8ugREdmxvBL+g1nQ0SxO11pIZfck6UtbOtwtdAAxnQXBHHtidu7lPcrBq1SEx26t1PQ==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "dependencies": {
- "hosted-git-info": "^7.0.0",
- "semver": "^7.3.5",
- "validate-npm-package-license": "^3.0.4"
- },
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": "^16.14.0 || >=18.0.0"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@knighted/duel/node_modules/path-scurry": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
- "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "node_modules/@oxc-parser/binding-freebsd-x64": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.116.0.tgz",
+ "integrity": "sha512-yo2/LaSXtlzKBurvNbwun/sN/RJwW3XhbMr069FwNVtft7GBnaLLdPIz/sf47icxw/BPViEX6wFvzeD12mtrAg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "dependencies": {
- "lru-cache": "^10.2.0",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
- },
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
"engines": {
- "node": ">=16 || 14 >=14.18"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@knighted/duel/node_modules/read-package-up": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
- "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==",
+ "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.116.0.tgz",
+ "integrity": "sha512-EiZeliIPPdFsuaPx8PzDMVijD/4YaUxO46/eYPk5raRocJqjjxOG6GAacQ8UrG3fbrgYjaEChfYL1e8DyE445A==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "dependencies": {
- "find-up-simple": "^1.0.0",
- "read-pkg": "^9.0.0",
- "type-fest": "^4.6.0"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@knighted/duel/node_modules/read-pkg": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
- "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
+ "node_modules/@oxc-parser/binding-linux-arm-musleabihf": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.116.0.tgz",
+ "integrity": "sha512-Nf7hnKRYRSIgglQcLAqE2St4b/Yr6dh+Z7in8mxol065Knevw71XZAiV1fmPSojq6uKPLV9eoH/wFrgr4TnZXw==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "dependencies": {
- "@types/normalize-package-data": "^2.4.3",
- "normalize-package-data": "^6.0.0",
- "parse-json": "^8.0.0",
- "type-fest": "^4.6.0",
- "unicorn-magic": "^0.1.0"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@knighted/duel/node_modules/unicorn-magic": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
- "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+ "node_modules/@oxc-parser/binding-linux-arm64-gnu": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.116.0.tgz",
+ "integrity": "sha512-9SJI0S4Qggn3QHpT8Y1jtZceA0m4BlpvO3ne2Wxd33UdTHMmelAnrXryjWutHWQtjCzOwSnFBEoQAdNNyt1u3A==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^20.19.0 || >=22.12.0"
}
},
- "node_modules/@knighted/specifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@knighted/specifier/-/specifier-1.0.1.tgz",
- "integrity": "sha512-LArFWJN7wGGLU1P3TeEHgO6wGKWEYq/o4/Yij7rnKk0ng1HbQn1wythI0E9Q7B3+7LRnposEtaeY9AZlE3Cg+Q==",
+ "node_modules/@oxc-parser/binding-linux-arm64-musl": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.116.0.tgz",
+ "integrity": "sha512-wMZ6//GI+q1JwO7G2OR51+eA5P8Gr3BobU8RAzCGJptvyGMkWb7KQ1E8s8naVZRr6bSGWAL2p3mCzKOxmEPmrA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-ppc64-gnu": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.116.0.tgz",
+ "integrity": "sha512-5BO0KCzTG2HZTnp3r6SCAOeCs/GwFBQJ1WAOG/ROfDf1fVVEy6hrtLKTLCuUMaamH38v+1+RVEmzRkzBj+rMDQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-riscv64-gnu": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.116.0.tgz",
+ "integrity": "sha512-M24gYb/ocVMnLwnH2wY5sLt4sRBkAUHDmfiYtyUYdKTkfPOKtpopd5otsL/BPLnIhpMD8zby4uXVvw7BU0UIlw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-riscv64-musl": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.116.0.tgz",
+ "integrity": "sha512-LHLXTHCH0bdvGjlitwr1ngeh32GAgq9HYzQ5VAgt0k0UT84AS8AkXj9Spoa9l20fXkVgSvAKcCEkydi4Ol23Dw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-s390x-gnu": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.116.0.tgz",
+ "integrity": "sha512-VE+XsztuE5jdHvLIDIQMuyDpz5NJGq1Vx/8EXYF0sS/gehlv9GhDpGVWU0SCZ/LjzIy4io/Z0W84UudqufvP3g==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-x64-gnu": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.116.0.tgz",
+ "integrity": "sha512-rxUkauyjjCmgA7BoR63ogRGEtgubROnCm8AXE9ydg+p42jCGLLqG05mFcS2eC+FYyAU58ZFJNXXeqFW1iCyTGQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-linux-x64-musl": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.116.0.tgz",
+ "integrity": "sha512-0zoZlk9MmXe6oTgSh5lT1D51SDC1bfwC96JmE1amMFAPdEbJk5MFRisfTN9TFBpBigQua65842tjaxqMiorAYw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-openharmony-arm64": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.116.0.tgz",
+ "integrity": "sha512-PGS7Xqik77U9WMyW626gAD5A2rSN629UvyYJKAl/tgpT+KqZI4+56pJfExhv8IW/PpSHjYHwjmakwobLikz8ww==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-wasm32-wasi": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.116.0.tgz",
+ "integrity": "sha512-lGNf/9PU8XxB4Gt1Gr1AKwSrjxGYa6os0PlrT4bpoQsfE3gaZonQTKwJyKhiQdgy7pBCI+ed1LB1NNib1FYULw==",
+ "cpu": [
+ "wasm32"
+ ],
"dev": true,
+ "optional": true,
"dependencies": {
- "@babel/parser": "^7.22.7",
- "@babel/traverse": "^7.23.2",
- "magic-string": "^0.30.1"
+ "@napi-rs/wasm-runtime": "^1.1.1"
},
"engines": {
- "node": ">=14"
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-arm64-msvc": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.116.0.tgz",
+ "integrity": "sha512-tcsOHE31duBSRQXZ7NfdtjmMKZwQYlS00PwAMJ4w5oXs3iPCvisUuIXP7Ko4FzeOBTRvkd64btxtQ6cRM0Kwlw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-ia32-msvc": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.116.0.tgz",
+ "integrity": "sha512-higCz/x+dOQ264YEk22hnu4RDqvjhfehjFORpxoh42QyUxsP6eIembYesBUu5ilALWo0HvRD+m89az2BSTwqpQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-parser/binding-win32-x64-msvc": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.116.0.tgz",
+ "integrity": "sha512-Lg2SRmVHpGG85knDVLbv44r1bYn0OpIV0vg9jVmoEIpDj3Q4kwXuQ6MWVtuslwHR8o2CSiqdBeEn1n1URrs6Eg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.116.0.tgz",
+ "integrity": "sha512-uOT8S1tlPmDckNxMNtIudN/yXpLdnhlJMX2oLS7cxCd7L0sUF09A/EbSVMWT3Y/iT44IwXCJSJfgfSxXAqWf9Q==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
}
},
"node_modules/@pkgjs/parseargs": {
@@ -1001,6 +1193,16 @@
"integrity": "sha512-eAWQzAjPj18tKnDzmWstz4OyWewLUNBm9tdoN9LayzoboRktYx3Enk1ZXPmThj55L7c4VWYq/Bzq0A51znZfhw==",
"dev": true
},
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -1155,6 +1357,38 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/antlr-ng": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/antlr-ng/-/antlr-ng-1.0.10.tgz",
+ "integrity": "sha512-fw3NdsQP3dabuZrDhKAMewrBsY5KSAcMrvhWBVDmHYegv5D51pypzCYK1PpjaRVKcVeP/5xKfqJY31TvXACOdA==",
+ "dev": true,
+ "dependencies": {
+ "antlr4ng": "3.0.16",
+ "commander": "13.1.0",
+ "stringtemplate4ts": "1.0.9",
+ "unicode-properties": "1.4.1"
+ },
+ "bin": {
+ "antlr-ng": "dist/cli/runner.js",
+ "grun": "dist/cli/TestRig.js",
+ "interpreter": "dist/cli/Interpreter.js",
+ "testrig": "dist/cli/TestRig.js"
+ }
+ },
+ "node_modules/antlr-ng/node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/antlr4ng": {
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/antlr4ng/-/antlr4ng-3.0.16.tgz",
+ "integrity": "sha512-DQuJkC7kX3xunfF4K2KsWTSvoxxslv+FQp/WHQZTJSsH2Ec3QfFmrxC3Nky2ok9yglXn6nHM4zUaVDxcN5f6kA=="
+ },
"node_modules/any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
@@ -1968,6 +2202,15 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
+ "node_modules/fast-printf": {
+ "version": "1.6.10",
+ "resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.10.tgz",
+ "integrity": "sha512-GwTgG9O4FVIdShhbVF3JxOgSBY2+ePGsu2V/UONgoCPzF9VY6ZdBMKsHKCYQHZwNk3qNouUolRDsgVxcVA5G1w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0"
+ }
+ },
"node_modules/figures": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
@@ -2005,16 +2248,16 @@
}
},
"node_modules/find-up": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz",
- "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-8.0.0.tgz",
+ "integrity": "sha512-JGG8pvDi2C+JxidYdIwQDyS/CgcrIdh18cvgxcBge3wSHRQOrooMD3GlFBcmMJAN9M42SAZjDp5zv1dglJjwww==",
"dev": true,
"dependencies": {
- "locate-path": "^7.1.0",
- "path-exists": "^5.0.0"
+ "locate-path": "^8.0.0",
+ "unicorn-magic": "^0.3.0"
},
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ "node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -2032,6 +2275,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/find-up/node_modules/unicorn-magic": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/flat": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
@@ -2094,6 +2349,18 @@
"node": "*"
}
},
+ "node_modules/get-tsconfig": {
+ "version": "4.13.6",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
+ "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
+ "dev": true,
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
"node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
@@ -2381,6 +2648,15 @@
"node": ">=8"
}
},
+ "node_modules/is-reference": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
+ "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "^1.0.6"
+ }
+ },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -2504,18 +2780,6 @@
"node": ">=10"
}
},
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
@@ -2534,12 +2798,6 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
- "node_modules/jsonc-parser": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
- "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
- "dev": true
- },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -2590,15 +2848,15 @@
}
},
"node_modules/locate-path": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
- "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-8.0.0.tgz",
+ "integrity": "sha512-XT9ewWAC43tiAV7xDAPflMkG0qOPn2QjHqlgX8FOqmWa/rxnyYDulF9T0F7tRy1u+TVTmK/M//6VIOye+2zDXg==",
"dev": true,
"dependencies": {
"p-locate": "^6.0.0"
},
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ "node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -3079,6 +3337,43 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/oxc-parser": {
+ "version": "0.116.0",
+ "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.116.0.tgz",
+ "integrity": "sha512-ugEo6wwqaqCGcpi7GsLCwSkoD7gIXzvtdaTxE+mbrXFYazU5Q9YdpZdAj9z2b79i/xlv+uW2aAvyzGAlpUzhKQ==",
+ "dev": true,
+ "dependencies": {
+ "@oxc-project/types": "^0.116.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ },
+ "optionalDependencies": {
+ "@oxc-parser/binding-android-arm-eabi": "0.116.0",
+ "@oxc-parser/binding-android-arm64": "0.116.0",
+ "@oxc-parser/binding-darwin-arm64": "0.116.0",
+ "@oxc-parser/binding-darwin-x64": "0.116.0",
+ "@oxc-parser/binding-freebsd-x64": "0.116.0",
+ "@oxc-parser/binding-linux-arm-gnueabihf": "0.116.0",
+ "@oxc-parser/binding-linux-arm-musleabihf": "0.116.0",
+ "@oxc-parser/binding-linux-arm64-gnu": "0.116.0",
+ "@oxc-parser/binding-linux-arm64-musl": "0.116.0",
+ "@oxc-parser/binding-linux-ppc64-gnu": "0.116.0",
+ "@oxc-parser/binding-linux-riscv64-gnu": "0.116.0",
+ "@oxc-parser/binding-linux-riscv64-musl": "0.116.0",
+ "@oxc-parser/binding-linux-s390x-gnu": "0.116.0",
+ "@oxc-parser/binding-linux-x64-gnu": "0.116.0",
+ "@oxc-parser/binding-linux-x64-musl": "0.116.0",
+ "@oxc-parser/binding-openharmony-arm64": "0.116.0",
+ "@oxc-parser/binding-wasm32-wasi": "0.116.0",
+ "@oxc-parser/binding-win32-arm64-msvc": "0.116.0",
+ "@oxc-parser/binding-win32-ia32-msvc": "0.116.0",
+ "@oxc-parser/binding-win32-x64-msvc": "0.116.0"
+ }
+ },
"node_modules/p-limit": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
@@ -3127,6 +3422,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
+ "dev": true
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -3156,15 +3457,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/path-exists": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
- "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- }
- },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -3199,6 +3491,17 @@
"node": "*"
}
},
+ "node_modules/periscopic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-4.0.2.tgz",
+ "integrity": "sha512-sqpQDUy8vgB7ycLkendSKS6HnVz1Rneoc3Rc+ZBUCe2pbqlVuCC5vF52l0NJ1aiMg/r1qfYF9/myz8CZeI2rjA==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "is-reference": "^3.0.2",
+ "zimmerframe": "^1.0.0"
+ }
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -3445,6 +3748,15 @@
"node": ">=4"
}
},
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -3633,6 +3945,33 @@
"node": ">=8"
}
},
+ "node_modules/stringtemplate4ts": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/stringtemplate4ts/-/stringtemplate4ts-1.0.9.tgz",
+ "integrity": "sha512-KYZm2bJlSjynG5Y+L46fkaKBQG6mhV6hb2RBA8dpx3/Vj6G4u7gwXNKYvaN9+QD5sj68/1srtSNDvqEso7MwsQ==",
+ "dev": true,
+ "dependencies": {
+ "antlr4ng": "3.0.15",
+ "fast-printf": "1.6.10",
+ "he": "1.2.0",
+ "luxon": "3.5.0"
+ }
+ },
+ "node_modules/stringtemplate4ts/node_modules/antlr4ng": {
+ "version": "3.0.15",
+ "resolved": "https://registry.npmjs.org/antlr4ng/-/antlr4ng-3.0.15.tgz",
+ "integrity": "sha512-VELFqTfcpGI2bj6ScMWuxM3FI6HOsojrgmnw3cCbUtsQ1DNOq32wJsjOt7vLvfIniyyuE1DIYegGcuFmn+jgyw==",
+ "dev": true
+ },
+ "node_modules/stringtemplate4ts/node_modules/luxon": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz",
+ "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -3757,6 +4096,12 @@
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
"dev": true
},
+ "node_modules/tiny-inflate": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
+ "dev": true
+ },
"node_modules/toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
@@ -3885,6 +4230,26 @@
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"dev": true
},
+ "node_modules/unicode-properties": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz",
+ "integrity": "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==",
+ "dev": true,
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "unicode-trie": "^2.0.0"
+ }
+ },
+ "node_modules/unicode-trie": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
+ "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
+ "dev": true,
+ "dependencies": {
+ "pako": "^0.2.5",
+ "tiny-inflate": "^1.0.0"
+ }
+ },
"node_modules/unicorn-magic": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz",
@@ -4189,6 +4554,12 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zimmerframe": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
+ "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
+ "dev": true
}
}
}
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json
index 4e36f33fc4..74256e8e25 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json
@@ -20,13 +20,19 @@
"type": "module",
"main": "./build/cjs/index.cjs",
"exports": {
- "import": "./build/esm/index.js",
- "require": "./build/cjs/index.cjs"
+ ".": {
+ "import": "./build/esm/index.js",
+ "require": "./build/cjs/index.cjs"
+ },
+ "./language": {
+ "import": "./build/esm/language/index.js"
+ }
},
"files": [
"build"
],
"dependencies": {
+ "antlr4ng": "~3.0.16",
"buffer": "^6.0.3",
"eventemitter3": "^5.0.1",
"readable-stream": "^4.5.2",
@@ -35,16 +41,17 @@
},
"devDependencies": {
"@cucumber/cucumber": "~12.7.0",
- "@knighted/duel": "^1.0.7",
+ "@eslint/js": "^9.16.0",
+ "@knighted/duel": "^4.0.2",
"@tsconfig/node18": "^18.2.2",
"@types/readable-stream": "^4.0.10",
"@types/uuid": "^9.0.8",
"@types/ws": "^8.5.10",
+ "antlr-ng": "^1.0.10",
"chai": "~4.5.0",
"chai-string": "~1.5.0",
"colors": "1.4.0",
"cross-env": "^10.1.0",
- "@eslint/js": "^9.16.0",
"eslint": "^9.36.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-prettier": "^5.0.0",
@@ -65,10 +72,13 @@
"url": "https://issues.apache.org/jira/browse/TINKERPOP"
},
"scripts": {
+ "postinstall": "node scripts/patch-antlr4ng.js",
+ "generate": "mkdir -p lib/language/grammar && antlr-ng -Dlanguage=TypeScript -visitor --generate-listener --exact-output-dir -o lib/language/grammar ../../../../../gremlin-language/src/main/antlr4/Gremlin.g4",
+ "prebuild": "npm run generate",
"build": "rm -rf build && duel --dirs",
- "prepare": "npm run build",
+ "prepare": "npm run generate && npm run build",
"test": "npm run unit-test && npm run integration-test",
- "unit-test": "cross-env TS_NODE_PROJECT='tsconfig.test.json' mocha test/unit/*",
+ "unit-test": "cross-env TS_NODE_PROJECT='tsconfig.test.json' mocha 'test/unit/**/*.js'",
"integration-test": "npm run integration-test-graphson30 && npm run integration-test-graphbinary",
"integration-test-graphson30": "cross-env TS_NODE_PROJECT='tsconfig.test.json' CLIENT_MIMETYPE='application/vnd.gremlin-v3.0+json' ./node_modules/mocha/bin/mocha.js test/integration -t 5000",
"integration-test-graphbinary": "cross-env TS_NODE_PROJECT='tsconfig.test.json' CLIENT_MIMETYPE='application/vnd.graphbinary-v1.0' ./node_modules/mocha/bin/mocha.js test/integration -t 5000",
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/scripts/patch-antlr4ng.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/scripts/patch-antlr4ng.js
new file mode 100644
index 0000000000..39a0a6a0b5
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/scripts/patch-antlr4ng.js
@@ -0,0 +1,60 @@
+#!/usr/bin/env node
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Patches antlr4ng to add CJS TypeScript declaration files.
+ *
+ * antlr4ng ships a CJS bundle (dist/index.cjs) but lacks the accompanying
+ * dist/index.d.cts type declarations that TypeScript's NodeNext module
+ * resolution requires when compiling CJS output. This script creates the
+ * missing .d.cts file and updates the package exports map so TypeScript
+ * correctly resolves types in both ESM and CJS contexts.
+ *
+ * This is a stop-gap until antlr4ng ships .d.cts files natively.
+ * Relevant issues/discussions:
+ * - https://github.com/mike-lischke/antlr4ng/issues/23 (CJS/ESM dual module support)
+ * - https://github.com/mike-lischke/antlr4ng/issues/26 (TypeScript resolution issues)
+ * - https://github.com/mike-lischke/antlr4ng/discussions/21 (Discussion on package structure)
+ */
+
+import { copyFileSync, readFileSync, writeFileSync } from 'node:fs';
+import { resolve, dirname } from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+const pkgDir = resolve(__dirname, '..', 'node_modules', 'antlr4ng');
+const distDir = resolve(pkgDir, 'dist');
+
+// Copy index.d.ts → index.d.cts
+const dts = resolve(distDir, 'index.d.ts');
+const dcts = resolve(distDir, 'index.d.cts');
+copyFileSync(dts, dcts);
+
+// Update exports map to include "types" in the "require" condition
+const pkgPath = resolve(pkgDir, 'package.json');
+const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
+pkg.exports = {
+ types: './dist/index.d.ts',
+ require: { types: './dist/index.d.cts', default: './dist/index.cjs' },
+ import: { types: './dist/index.d.ts', default: './dist/index.mjs' },
+};
+writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
+
+console.log('antlr4ng patched: added dist/index.d.cts and updated exports map');
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator/corpus-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator/corpus-test.js
new file mode 100644
index 0000000000..a88b1613c7
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator/corpus-test.js
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import assert from 'assert';
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+import { GremlinTranslator } from '../../../lib/language/translator/GremlinTranslator.js';
+import { TranslatorException } from '../../../lib/language/translator/TranslatorException.js';
+import { Translator } from '../../../lib/language/translator/Translator.js';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+// Search for translations.json up from the current directory
+function findTranslationsPath() {
+ let current = __dirname;
+ while (current !== path.parse(current).root) {
+ const p = path.join(
+ current,
+ 'gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json',
+ );
+ if (fs.existsSync(p)) return p;
+ current = path.dirname(current);
+ }
+ return null;
+}
+
+const translationsPath = findTranslationsPath();
+
+describe('GremlinTranslator corpus', function () {
+ let scenarios = [];
+ if (translationsPath && fs.existsSync(translationsPath)) {
+ scenarios = JSON.parse(fs.readFileSync(translationsPath, 'utf8'));
+ }
+
+ it('translations.json should be present and loaded', function () {
+ assert.ok(
+ translationsPath !== null,
+ 'Could not find translations.json in the project structure. Run mvn generate-resources in gremlin-test.',
+ );
+ assert.ok(scenarios.length > 0, 'translations.json is empty');
+ });
+
+ describe('per-scenario translation', function () {
+ scenarios.forEach((scenario) => {
+ scenario.traversals.forEach((traversal) => {
+ const { original } = traversal;
+
+ // JavaScript
+ const jsExpected = traversal['javascript'];
+ if (jsExpected !== undefined && jsExpected !== null) {
+ it(`[javascript] translates [${scenario.scenario}]: ${original}`, function () {
+ const result = GremlinTranslator.translate(original, 'g', 'JAVASCRIPT');
+ assert.strictEqual(result.getTranslated(), jsExpected);
+ });
+ } else {
+ it(`[javascript] throws for untranslatable [${scenario.scenario}]: ${original}`, function () {
+ assert.throws(() => GremlinTranslator.translate(original, 'g', 'JAVASCRIPT'), TranslatorException);
+ });
+ }
+
+ // Python
+ const pyExpected = traversal['python'];
+ if (pyExpected !== undefined && pyExpected !== null) {
+ it(`[python] translates [${scenario.scenario}]: ${original}`, function () {
+ const result = GremlinTranslator.translate(original, 'g', 'PYTHON');
+ assert.strictEqual(result.getTranslated(), pyExpected);
+ });
+ } else {
+ it(`[python] throws for untranslatable [${scenario.scenario}]: ${original}`, function () {
+ assert.throws(() => GremlinTranslator.translate(original, 'g', 'PYTHON'), TranslatorException);
+ });
+ }
+
+ // .NET
+ const dotnetExpected = traversal['dotnet'];
+ if (dotnetExpected !== undefined && dotnetExpected !== null) {
+ it(`[dotnet] translates [${scenario.scenario}]: ${original}`, function () {
+ const result = GremlinTranslator.translate(original, 'g', 'DOTNET');
+ assert.strictEqual(result.getTranslated(), dotnetExpected);
+ });
+ } else {
+ it(`[dotnet] throws for untranslatable [${scenario.scenario}]: ${original}`, function () {
+ assert.throws(() => GremlinTranslator.translate(original, 'g', 'DOTNET'), TranslatorException);
+ });
+ }
+
+ // Go
+ const goExpected = traversal['go'];
+ if (goExpected !== undefined && goExpected !== null) {
+ it(`[go] translates [${scenario.scenario}]: ${original}`, function () {
+ const result = GremlinTranslator.translate(original, 'g', 'GO');
+ assert.strictEqual(result.getTranslated(), goExpected);
+ });
+ } else {
+ it(`[go] throws for untranslatable [${scenario.scenario}]: ${original}`, function () {
+ assert.throws(() => GremlinTranslator.translate(original, 'g', 'GO'), TranslatorException);
+ });
+ }
+
+ // Anonymized
+ const anonymizedExpected = traversal['anonymized'];
+ if (anonymizedExpected !== undefined && anonymizedExpected !== null) {
+ it(`[anonymized] translates [${scenario.scenario}]: ${original}`, function () {
+ const result = GremlinTranslator.translate(original, 'g', 'ANONYMIZED');
+ assert.strictEqual(result.getTranslated(), anonymizedExpected);
+ });
+ } else {
+ it(`[anonymized] throws for untranslatable [${scenario.scenario}]: ${original}`, function () {
+ assert.throws(() => GremlinTranslator.translate(original, 'g', 'ANONYMIZED'), TranslatorException);
+ });
+ }
+
+ // Groovy
+ const groovyExpected = traversal['groovy'];
+ if (groovyExpected !== undefined && groovyExpected !== null) {
+ it(`[groovy] translates [${scenario.scenario}]: ${original}`, function () {
+ const result = GremlinTranslator.translate(original, 'g', 'GROOVY');
+ assert.strictEqual(result.getTranslated(), groovyExpected);
+ });
+ } else {
+ it(`[groovy] throws for untranslatable [${scenario.scenario}]: ${original}`, function () {
+ assert.throws(() => GremlinTranslator.translate(original, 'g', 'GROOVY'), TranslatorException);
+ });
+ }
+
+ // Java
+ const javaExpected = traversal['java'];
+ if (javaExpected !== undefined && javaExpected !== null) {
+ it(`[java] translates [${scenario.scenario}]: ${original}`, function () {
+ const result = GremlinTranslator.translate(original, 'g', 'JAVA');
+ assert.strictEqual(result.getTranslated(), javaExpected);
+ });
+ } else {
+ it(`[java] throws for untranslatable [${scenario.scenario}]: ${original}`, function () {
+ assert.throws(() => GremlinTranslator.translate(original, 'g', 'JAVA'), TranslatorException);
+ });
+ }
+ });
+ });
+ });
+});
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator/gremlin-translator-test.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator/gremlin-translator-test.js
new file mode 100644
index 0000000000..f95d8d47df
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/unit/translator/gremlin-translator-test.js
@@ -0,0 +1,550 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import assert from 'assert';
+import { GremlinTranslator } from '../../../lib/language/translator/GremlinTranslator.js';
+import { TranslatorException } from '../../../lib/language/translator/TranslatorException.js';
+import { Translator } from '../../../lib/language/translator/Translator.js';
+import TranslateVisitor from '../../../lib/language/translator/TranslateVisitor.js';
+import JavascriptTranslateVisitor from '../../../lib/language/translator/JavascriptTranslateVisitor.js';
+import PythonTranslateVisitor from '../../../lib/language/translator/PythonTranslateVisitor.js';
+import GoTranslateVisitor from '../../../lib/language/translator/GoTranslateVisitor.js';
+import DotNetTranslateVisitor from '../../../lib/language/translator/DotNetTranslateVisitor.js';
+import JavaTranslateVisitor from '../../../lib/language/translator/JavaTranslateVisitor.js';
+import GroovyTranslateVisitor from '../../../lib/language/translator/GroovyTranslateVisitor.js';
+import AnonymizedTranslateVisitor from '../../../lib/language/translator/AnonymizedTranslateVisitor.js';
+
+describe('GremlinTranslator', function () {
+ describe('basic translation', function () {
+ const tests = [
+ // basic traversals
+ ['g.V()', 'g.V()'],
+ ['g.V(1)', 'g.V(1)'],
+ ['g.V("name")', 'g.V("name")'],
+ ['g.V().hasLabel("person")', 'g.V().hasLabel("person")'],
+ ['g.V().out("knows")', 'g.V().out("knows")'],
+ // reserved word mapping
+ ['g.V().in("knows")', 'g.V().in_("knows")'],
+ ['g.V().from("a")', 'g.V().from_("a")'],
+ // anonymous traversal
+ ['g.V().where(__.out("knows"))', 'g.V().where(__.out("knows"))'],
+ // enum explicit naming
+ ['g.V().order().by(T.id)', 'g.V().order().by(T.id)'],
+ ['g.V().order().by(Order.asc)', 'g.V().order().by(Order.asc)'],
+ // predicates
+ ['g.V().has("age", P.gt(30))', 'g.V().has("age", P.gt(30))'],
+ ['g.V().has("name", TextP.containing("mar"))', 'g.V().has("name", TextP.containing("mar"))'],
+ // integer suffix stripping
+ ['g.V().range(0, 10l)', 'g.V().range(0, 10)'],
+ // float suffix stripping
+ ['g.V().has("weight", P.gt(0.5f))', 'g.V().has("weight", P.gt(0.5))'],
+ // Map literal
+ ['g.addV("person").property(T.id, [(T.label): "person"])', 'g.addV("person").property(T.id, new Map([[T.label, "person"]]))'],
+ // Set literal
+ ['g.inject({1,2,3})', 'g.inject(new Set([1, 2, 3]))'],
+ // Collection literal
+ ['g.inject([1,2,3])', 'g.inject([1, 2, 3])'],
+ // Nan/Inf
+ ['g.inject(NaN)', 'g.inject(Number.NaN)'],
+ ['g.inject(Infinity)', 'g.inject(Number.POSITIVE_INFINITY)'],
+ ['g.inject(-Infinity)', 'g.inject(Number.NEGATIVE_INFINITY)'],
+ ];
+
+ tests.forEach(function ([input, expected]) {
+ it(`translates: ${input}`, function () {
+ const result = GremlinTranslator.translate(input);
+ assert.strictEqual(result.getTranslated(), expected);
+ });
+ });
+ });
+
+ describe('custom graphTraversalSourceName', function () {
+ it('uses custom source name', function () {
+ const result = GremlinTranslator.translate('g.V()', 'source');
+ assert.strictEqual(result.getTranslated(), 'source.V()');
+ });
+ });
+
+ describe('Translator registry', function () {
+ it('accepts JAVASCRIPT key', function () {
+ const result = GremlinTranslator.translate('g.V()', 'g', 'JAVASCRIPT');
+ assert.strictEqual(result.getTranslated(), 'g.V()');
+ });
+
+ it('has JAVASCRIPT factory', function () {
+ const visitor = Translator.JAVASCRIPT('g');
+ assert.ok(visitor instanceof JavascriptTranslateVisitor);
+ });
+ });
+
+ describe('custom visitor', function () {
+ it('accepts TranslateVisitor subclass directly', function () {
+ const visitor = new JavascriptTranslateVisitor('myG');
+ const result = GremlinTranslator.translate('g.V()', 'myG', visitor);
+ assert.strictEqual(result.getTranslated(), 'myG.V()');
+ });
+ });
+
+ describe('parameter tracking', function () {
+ it('tracks variables as parameters', function () {
+ const result = GremlinTranslator.translate('g.V(vid1)');
+ assert.ok(result.getParameters().has('vid1'));
+ });
+
+ it('returns original query', function () {
+ const query = 'g.V().hasLabel("person")';
+ const result = GremlinTranslator.translate(query);
+ assert.strictEqual(result.getOriginal(), query);
+ });
+ });
+
+ describe('range literals throw', function () {
+ it('throws TranslatorException for range literal', function () {
+ assert.throws(
+ () => GremlinTranslator.translate('g.inject(1..5)'),
+ TranslatorException,
+ );
+ });
+ });
+});
+
+describe('PythonTranslateVisitor', function () {
+ const translate = (q) => GremlinTranslator.translate(q, 'g', 'PYTHON').getTranslated();
+
+ describe('basic translation', function () {
+ const tests = [
+ // basic traversals — camelCase methods become snake_case
+ ['g.V()', 'g.V()'],
+ ['g.V(1)', 'g.V(1)'],
+ ['g.V("name")', "g.V('name')"],
+ ['g.V().hasLabel("person")', "g.V().has_label('person')"],
+ ['g.V().out("knows")', "g.V().out('knows')"],
+ // reserved word mapping
+ ['g.V().in("knows")', "g.V().in_('knows')"],
+ ['g.V().from("a")', "g.V().from_('a')"],
+ ['g.V().filter(__.has("name"))', 'g.V().filter_(__.has(\'name\'))'],
+ // string literals use single quotes
+ ['g.V().has("name", "marko")', "g.V().has('name', 'marko')"],
+ // boolean capitalisation
+ ['g.V().has("active", true)', "g.V().has('active', True)"],
+ ['g.V().has("active", false)', "g.V().has('active', False)"],
+ // null → None
+ ['g.V().has("name", null)', "g.V().has('name', None)"],
+ // enum explicit naming — T.id → T.id_ in Python (id is a builtin)
+ ['g.V().order().by(T.id)', 'g.V().order().by(T.id_)'],
+ ['g.V().order().by(Order.asc)', 'g.V().order().by(Order.asc)'],
+ // camelCase step names → snake_case
+ ['g.V().valueMap()', 'g.V().value_map()'],
+ ['g.V().outE()', 'g.V().out_e()'],
+ // predicates
+ ['g.V().has("age", P.gt(30))', "g.V().has('age', P.gt(30))"],
+ ['g.V().has("name", TextP.containing("mar"))', "g.V().has('name', TextP.containing('mar'))"],
+ // integer suffix stripping
+ ['g.V().range(0, 10l)', 'g.V().range_(0, long(10))'],
+ // float suffix stripping
+ ['g.V().has("weight", P.gt(0.5f))', "g.V().has('weight', P.gt(0.5))"],
+ // NaN/Inf
+ ["g.inject(NaN)", "g.inject(float('nan'))"],
+ ["g.inject(Infinity)", "g.inject(float('inf'))"],
+ ["g.inject(-Infinity)", "g.inject(float('-inf'))"],
+ // Collection literals
+ ['g.inject([1,2,3])', 'g.inject([1, 2, 3])'],
+ // Set literal (non-empty)
+ ['g.inject({1,2,3})', 'g.inject({1, 2, 3})'],
+ // Map literal — T.id → T.id_ in Python
+ ['g.addV("person").property(T.id, [(T.label): "person"])', "g.add_v('person').property(T.id_, { T.label: 'person' })"],
+ ];
+
+ tests.forEach(function ([input, expected]) {
+ it(`translates: ${input}`, function () {
+ assert.strictEqual(translate(input), expected);
+ });
+ });
+ });
+
+ describe('Translator registry', function () {
+ it('accepts PYTHON key', function () {
+ const result = GremlinTranslator.translate('g.V()', 'g', 'PYTHON');
+ assert.strictEqual(result.getTranslated(), 'g.V()');
+ });
+
+ it('has PYTHON factory', function () {
+ const visitor = Translator.PYTHON('g');
+ assert.ok(visitor instanceof PythonTranslateVisitor);
+ });
+ });
+
+ describe('range literals throw', function () {
+ it('throws TranslatorException for range literal', function () {
+ assert.throws(
+ () => GremlinTranslator.translate('g.inject(1..5)', 'g', 'PYTHON'),
+ TranslatorException,
+ );
+ });
+ });
+});
+
+describe('GoTranslateVisitor', function () {
+ const translate = (q) => GremlinTranslator.translate(q, 'g', 'GO').getTranslated();
+
+ describe('basic translation', function () {
+ const tests = [
+ // basic traversals — all step methods become PascalCase
+ ['g.V()', 'g.V()'],
+ ['g.V(1)', 'g.V(1)'],
+ ['g.V("name")', 'g.V("name")'],
+ ['g.V().hasLabel("person")', 'g.V().HasLabel("person")'],
+ ['g.V().out("knows")', 'g.V().Out("knows")'],
+ // anonymous traversal uses gremlingo.T__.
+ ['g.V().where(__.out("knows"))', 'g.V().Where(gremlingo.T__.Out("knows"))'],
+ // enum explicit naming with gremlingo. prefix
+ ['g.V().order().by(T.id)', 'g.V().Order().By(gremlingo.T.Id)'],
+ ['g.V().order().by(Order.asc)', 'g.V().Order().By(gremlingo.Order.Asc)'],
+ // predicates get gremlingo. prefix and PascalCase method
+ ['g.V().has("age", P.gt(30))', 'g.V().Has("age", gremlingo.P.Gt(30))'],
+ ['g.V().has("name", TextP.containing("mar"))', 'g.V().Has("name", gremlingo.TextP.Containing("mar"))'],
+ // integer suffixes become Go type casts
+ ['g.V().range(0, 10l)', 'g.V().Range(0, int64(10))'],
+ // float suffix
+ ['g.V().has("weight", P.gt(0.5f))', 'g.V().Has("weight", gremlingo.P.Gt(float32(0.5)))'],
+ // Map literal
+ ['g.addV("person").property(T.id, [(T.label): "person"])', 'g.AddV("person").Property(gremlingo.T.Id, map[interface{}]interface{}{gremlingo.T.Label: "person" })'],
+ // Set literal
+ ['g.inject({1,2,3})', 'g.Inject(gremlingo.NewSimpleSet(1, 2, 3))'],
+ // Collection literal
+ ['g.inject([1,2,3])', 'g.Inject([]interface{}{1, 2, 3})'],
+ // NaN/Inf
+ ['g.inject(NaN)', 'g.Inject(math.NaN())'],
+ ['g.inject(Infinity)', 'g.Inject(math.Inf(1))'],
+ ['g.inject(-Infinity)', 'g.Inject(math.Inf(-1))'],
+ // null → nil
+ ['g.V().has("name", null)', 'g.V().Has("name", nil)'],
+ ];
+
+ tests.forEach(function ([input, expected]) {
+ it(`translates: ${input}`, function () {
+ assert.strictEqual(translate(input), expected);
+ });
+ });
+ });
+
+ describe('Translator registry', function () {
+ it('accepts GO key', function () {
+ const result = GremlinTranslator.translate('g.V()', 'g', 'GO');
+ assert.strictEqual(result.getTranslated(), 'g.V()');
+ });
+
+ it('has GO factory', function () {
+ const visitor = Translator.GO('g');
+ assert.ok(visitor instanceof GoTranslateVisitor);
+ });
+ });
+
+ describe('range literals throw', function () {
+ it('throws TranslatorException for range literal', function () {
+ assert.throws(
+ () => GremlinTranslator.translate('g.inject(1..5)', 'g', 'GO'),
+ TranslatorException,
+ );
+ });
+ });
+});
+
+describe('DotNetTranslateVisitor', function () {
+ const translate = (q) => GremlinTranslator.translate(q, 'g', 'DOTNET').getTranslated();
+
+ describe('basic translation', function () {
+ const tests = [
+ // basic traversals — all step methods become PascalCase
+ ['g.V()', 'g.V()'],
+ ['g.V(1)', 'g.V(1)'],
+ ['g.V("name")', 'g.V("name")'],
+ ['g.V().hasLabel("person")', 'g.V().HasLabel("person")'],
+ ['g.V().out("knows")', 'g.V().Out("knows")'],
+ // anonymous traversal uses __. (no prefix)
+ ['g.V().where(__.out("knows"))', 'g.V().Where(__.Out("knows"))'],
+ // enum naming: prefix as-is, value capitalized
+ ['g.V().order().by(T.id)', 'g.V().Order().By(T.Id)'],
+ ['g.V().order().by(Order.asc)', 'g.V().Order().By(Order.Asc)'],
+ // predicates: PascalCase method name
+ ['g.V().has("age", P.gt(30))', 'g.V().Has("age", P.Gt(30))'],
+ ['g.V().has("name", TextP.containing("mar"))', 'g.V().Has("name", TextP.Containing("mar"))'],
+ // integer suffixes
+ ['g.V().range(0, 10l)', 'g.V().Range<object>(0, 10l)'],
+ ['g.V().range(0, 5i)', 'g.V().Range<object>(0, 5)'],
+ // float suffixes — f/d kept for C#
+ ['g.V().has("weight", P.gt(0.5f))', 'g.V().Has("weight", P.Gt(0.5f))'],
+ // NaN / Inf
+ ['g.inject(NaN)', 'g.Inject<object>(Double.NaN)'],
+ ['g.inject(Infinity)', 'g.Inject<object>(Double.PositiveInfinity)'],
+ ['g.inject(-Infinity)', 'g.Inject<object>(Double.NegativeInfinity)'],
+ // Collections
+ ['g.inject([1,2,3])', 'g.Inject<object>(new List<object> { 1, 2, 3 })'],
+ ['g.inject({1,2,3})', 'g.Inject<object>(new HashSet<object> { 1, 2, 3 })'],
+ // Map literal
+ ['g.addV("person").property(T.id, [(T.label): "person"])', 'g.AddV((string) "person").Property(T.Id, new Dictionary<object, object> {{ T.Label, "person" }})'],
+ // values gets <object>
+ ['g.V().values("name")', 'g.V().Values<object>("name")'],
+ // null cast
+ ['g.V().has("name", null)', 'g.V().Has("name", (object) null)'],
+ ];
+
+ tests.forEach(function ([input, expected]) {
+ it(`translates: ${input}`, function () {
+ assert.strictEqual(translate(input), expected);
+ });
+ });
+ });
+
+ describe('Translator registry', function () {
+ it('accepts DOTNET key', function () {
+ const result = GremlinTranslator.translate('g.V()', 'g', 'DOTNET');
+ assert.strictEqual(result.getTranslated(), 'g.V()');
+ });
+
+ it('has DOTNET factory', function () {
+ const visitor = Translator.DOTNET('g');
+ assert.ok(visitor instanceof DotNetTranslateVisitor);
+ });
+ });
+
+ describe('range literals throw', function () {
+ it('throws TranslatorException for range literal', function () {
+ assert.throws(
+ () => GremlinTranslator.translate('g.inject(1..5)', 'g', 'DOTNET'),
+ TranslatorException,
+ );
+ });
+ });
+});
+
+describe('JavaTranslateVisitor', function () {
+ const translate = (q) => GremlinTranslator.translate(q, 'g', 'JAVA').getTranslated();
+
+ describe('basic translation', function () {
+ const tests = [
+ // basic traversals — camelCase preserved
+ ['g.V()', 'g.V()'],
+ ['g.V(1)', 'g.V(1)'],
+ ['g.V("name")', 'g.V("name")'],
+ ['g.V().hasLabel("person")', 'g.V().hasLabel("person")'],
+ ['g.V().out("knows")', 'g.V().out("knows")'],
+ // anonymous traversal
+ ['g.V().where(__.out("knows"))', 'g.V().where(__.out("knows"))'],
+ // enum explicit naming — base class handles, as-is
+ ['g.V().order().by(T.id)', 'g.V().order().by(T.id)'],
+ ['g.V().order().by(Order.asc)', 'g.V().order().by(Order.asc)'],
+ // predicates
+ ['g.V().has("age", P.gt(30))', 'g.V().has("age", P.gt(30))'],
+ ['g.V().has("name", TextP.containing("mar"))', 'g.V().has("name", TextP.containing("mar"))'],
+ // integer suffixes
+ ['g.V().range(0, 10l)', 'g.V().range(0, 10l)'],
+ ['g.inject(1b)', 'g.inject(new Byte(1))'],
+ ['g.inject(1s)', 'g.inject(new Short(1))'],
+ ['g.inject(1i)', 'g.inject(1)'],
+ ['g.inject(1n)', 'g.inject(new BigInteger("1"))'],
+ // float suffixes
+ ['g.V().has("weight", P.gt(0.5f))', 'g.V().has("weight", P.gt(0.5f))'],
+ // NaN/Inf
+ ['g.inject(NaN)', 'g.inject(Double.NaN)'],
+ ['g.inject(Infinity)', 'g.inject(Double.POSITIVE_INFINITY)'],
+ ['g.inject(-Infinity)', 'g.inject(Double.NEGATIVE_INFINITY)'],
+ // Collection literals
+ ['g.inject([1,2,3])', 'g.inject(new ArrayList<Object>() {{ add(1); add(2); add(3); }})'],
+ // Set literal
+ ['g.inject({1,2,3})', 'g.inject(new HashSet<Object>() {{ add(1); add(2); add(3); }})'],
+ // Map literal
+ ['g.addV("person").property(T.id, [(T.label): "person"])', 'g.addV("person").property(T.id, new LinkedHashMap<Object, Object>() {{ put(T.label, "person"); }})'],
+ ];
+
+ tests.forEach(function ([input, expected]) {
+ it(`translates: ${input}`, function () {
+ assert.strictEqual(translate(input), expected);
+ });
+ });
+ });
+
+ describe('Translator registry', function () {
+ it('accepts JAVA key', function () {
+ const result = GremlinTranslator.translate('g.V()', 'g', 'JAVA');
+ assert.strictEqual(result.getTranslated(), 'g.V()');
+ });
+
+ it('has JAVA factory', function () {
+ const visitor = Translator.JAVA('g');
+ assert.ok(visitor instanceof JavaTranslateVisitor);
+ });
+ });
+
+ describe('range literals throw', function () {
+ it('throws TranslatorException for range literal', function () {
+ assert.throws(
+ () => GremlinTranslator.translate('g.inject(1..5)', 'g', 'JAVA'),
+ TranslatorException,
+ );
+ });
+ });
+});
+
+describe('GroovyTranslateVisitor', function () {
+ const translate = (q) => GremlinTranslator.translate(q, 'g', 'GROOVY').getTranslated();
+
+ describe('basic translation', function () {
+ const tests = [
+ // basic traversals — camelCase preserved
+ ['g.V()', 'g.V()'],
+ ['g.V(1)', 'g.V(1)'],
+ ['g.V("name")', 'g.V("name")'],
+ ['g.V().hasLabel("person")', 'g.V().hasLabel("person")'],
+ ['g.V().out("knows")', 'g.V().out("knows")'],
+ // anonymous traversal
+ ['g.V().where(__.out("knows"))', 'g.V().where(__.out("knows"))'],
+ // enum explicit naming — base class handles, as-is
+ ['g.V().order().by(T.id)', 'g.V().order().by(T.id)'],
+ ['g.V().order().by(Order.asc)', 'g.V().order().by(Order.asc)'],
+ // predicates
+ ['g.V().has("age", P.gt(30))', 'g.V().has("age", P.gt(30))'],
+ ['g.V().has("name", TextP.containing("mar"))', 'g.V().has("name", TextP.containing("mar"))'],
+ // integer suffixes
+ ['g.V().range(0, 10l)', 'g.V().range(0, 10l)'],
+ ['g.inject(1b)', 'g.inject((byte)1)'],
+ ['g.inject(1s)', 'g.inject((short)1)'],
+ ['g.inject(1i)', 'g.inject(1i)'],
+ ['g.inject(1n)', 'g.inject(1g)'],
+ // float suffixes
+ ['g.V().has("weight", P.gt(0.5f))', 'g.V().has("weight", P.gt(0.5f))'],
+ // NaN — base class outputs NaN as-is
+ ['g.inject(NaN)', 'g.inject(NaN)'],
+ // Infinity
+ ['g.inject(Infinity)', 'g.inject(Double.POSITIVE_INFINITY)'],
+ ['g.inject(-Infinity)', 'g.inject(Double.NEGATIVE_INFINITY)'],
+ // Collection literals — base class handles as [items]
+ ['g.inject([1,2,3])', 'g.inject([1, 2, 3])'],
+ // Set literal — Groovy: [items] as Set
+ ['g.inject({1,2,3})', 'g.inject([1, 2, 3] as Set)'],
+ // Map literal — Groovy preserves parens on expression keys
+ ['g.addV("person").property(T.id, [(T.label): "person"])', 'g.addV("person").property(T.id, [(T.label):"person"])'],
+ // null as Map in mergeV
+ ['g.mergeV(null)', 'g.mergeV((Map) null)'],
+ // strategy no-args: output name as-is
+ ['g.withStrategies(AdjacentToIncidentStrategy).V()', 'g.withStrategies(AdjacentToIncidentStrategy).V()'],
+ // strategy with args: prepend new
+ ['g.withStrategies(EdgeLabelVerificationStrategy(throwException: true, logWarning: false)).V().out()', 'g.withStrategies(new EdgeLabelVerificationStrategy(throwException:true, logWarning:false)).V().out()'],
+ // withoutStrategies: no .class suffix
+ ['g.withoutStrategies(EarlyLimitStrategy).V()', 'g.withoutStrategies(EarlyLimitStrategy).V()'],
+ ];
+
+ tests.forEach(function ([input, expected]) {
+ it(`translates: ${input}`, function () {
+ assert.strictEqual(translate(input), expected);
+ });
+ });
+ });
+
+ describe('Translator registry', function () {
+ it('accepts GROOVY key', function () {
+ const result = GremlinTranslator.translate('g.V()', 'g', 'GROOVY');
+ assert.strictEqual(result.getTranslated(), 'g.V()');
+ });
+
+ it('has GROOVY factory', function () {
+ const visitor = Translator.GROOVY('g');
+ assert.ok(visitor instanceof GroovyTranslateVisitor);
+ });
+ });
+});
+
+describe('AnonymizedTranslateVisitor', function () {
+ const translate = (q) => GremlinTranslator.translate(q, 'g', 'ANONYMIZED').getTranslated();
+
+ describe('basic anonymization', function () {
+ const tests = [
+ // structure preserved, strings replaced
+ ['g.V().hasLabel("person")', 'g.V().hasLabel(string0)'],
+ // same value reuses same placeholder
+ ['g.V().has("name", "name")', 'g.V().has(string0, string0)'],
+ // different string values get different placeholders
+ ['g.V().has("age", "marko")', 'g.V().has(string0, string1)'],
+ // plain numbers — no suffix → number
+ ['g.V().has("age", P.gt(30))', 'g.V().has(string0, P.gt(number0))'],
+ ['g.V().has("age", P.between(26, 30))', 'g.V().has(string0, P.between(number0, number1))'],
+ // integer suffix i → integer
+ ['g.inject(1i)', 'g.inject(integer0)'],
+ // integer suffix l → long
+ ['g.inject(10l)', 'g.inject(long0)'],
+ // integer suffix b → byte
+ ['g.inject(1b)', 'g.inject(byte0)'],
+ // integer suffix s → short
+ ['g.inject(1s)', 'g.inject(short0)'],
+ // integer suffix n → biginteger
+ ['g.inject(1n)', 'g.inject(biginteger0)'],
+ // float suffix f → float
+ ['g.inject(0.5f)', 'g.inject(float0)'],
+ // float suffix d → double
+ ['g.inject(0.5d)', 'g.inject(double0)'],
+ // float suffix m → bigdecimal
+ ['g.inject(1.5m)', 'g.inject(bigdecimal0)'],
+ // NaN → number
+ ['g.inject(NaN)', 'g.inject(number0)'],
+ // Infinity → number
+ ['g.inject(Infinity)', 'g.inject(number0)'],
+ ['-Infinity' + '' , 'number0'], // handled via inject below
+ // boolean
+ ['g.inject(true)', 'g.inject(boolean0)'],
+ ['g.inject(false)', 'g.inject(boolean0)'],
+ // null → object
+ ['g.inject(null)', 'g.inject(object0)'],
+ // collection → list
+ ['g.inject([1,2,3])', 'g.inject(list0)'],
+ // set → set
+ ['g.inject({1,2,3})', 'g.inject(set0)'],
+ // map → map
+ ['g.addV("person").property(T.id, [(T.label): "person"])', 'g.addV(string0).property(T.id, map0)'],
+ // enums/traversal steps pass through unchanged
+ ['g.V().order().by(T.id)', 'g.V().order().by(T.id)'],
+ ['g.V().order().by(Order.asc)', 'g.V().order().by(Order.asc)'],
+ // variables pass through unchanged
+ ['g.V(vid1)', 'g.V(vid1)'],
+ ];
+
+ tests
+ .filter(([input]) => !input.startsWith('-Infinity'))
+ .forEach(function ([input, expected]) {
+ it(`anonymizes: ${input}`, function () {
+ assert.strictEqual(translate(input), expected);
+ });
+ });
+
+ it('anonymizes: g.inject(-Infinity)', function () {
+ assert.strictEqual(translate('g.inject(-Infinity)'), 'g.inject(number0)');
+ });
+ });
+
+ describe('Translator registry', function () {
+ it('accepts ANONYMIZED key', function () {
+ const result = GremlinTranslator.translate('g.V()', 'g', 'ANONYMIZED');
+ assert.strictEqual(result.getTranslated(), 'g.V()');
+ });
+
+ it('has ANONYMIZED factory', function () {
+ const visitor = Translator.ANONYMIZED('g');
+ assert.ok(visitor instanceof AnonymizedTranslateVisitor);
+ });
+ });
+});
diff --git a/gremlin-mcp/src/main/javascript/package-lock.json b/gremlin-mcp/src/main/javascript/package-lock.json
index a6c7d421a2..0f3a17818e 100644
--- a/gremlin-mcp/src/main/javascript/package-lock.json
+++ b/gremlin-mcp/src/main/javascript/package-lock.json
@@ -16,6 +16,7 @@
"@types/gremlin": "^3.6.7",
"effect": "^3.17.9",
"gremlin": "^3.7.4",
+ "gremlin-language": "file:../../../../gremlin-javascript/src/main/javascript/gremlin-javascript",
"gremlint": "~3.8.0",
"winston": "^3.17.0",
"zod": "^3.25.76"
@@ -43,6 +44,47 @@
"node": ">=20"
}
},
+ "../../../../gremlin-javascript/src/main/javascript/gremlin-javascript": {
+ "name": "gremlin",
+ "version": "4.0.0-alpha1",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "antlr4ng": "~3.0.16",
+ "buffer": "^6.0.3",
+ "eventemitter3": "^5.0.1",
+ "readable-stream": "^4.5.2",
+ "uuid": "^9.0.1",
+ "ws": "^8.16.0"
+ },
+ "devDependencies": {
+ "@cucumber/cucumber": "~12.7.0",
+ "@eslint/js": "^9.16.0",
+ "@knighted/duel": "^4.0.2",
+ "@tsconfig/node18": "^18.2.2",
+ "@types/readable-stream": "^4.0.10",
+ "@types/uuid": "^9.0.8",
+ "@types/ws": "^8.5.10",
+ "antlr-ng": "^1.0.10",
+ "chai": "~4.5.0",
+ "chai-string": "~1.5.0",
+ "colors": "1.4.0",
+ "cross-env": "^10.1.0",
+ "eslint": "^9.36.0",
+ "eslint-config-prettier": "^10.0.1",
+ "eslint-plugin-prettier": "^5.0.0",
+ "globals": "^15.14.0",
+ "js-yaml": "^3.14.2",
+ "jsdoc": "^4.0.5",
+ "mocha": "^11.7.5",
+ "prettier": "^3.0.0",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.4.2"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
"node_modules/@ampproject/remapping": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -3124,7 +3166,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
- "license": "MIT",
"dependencies": {
"event-target-shim": "^5.0.0"
},
@@ -3402,8 +3443,7 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ],
- "license": "MIT"
+ ]
},
"node_modules/body-parser": {
"version": "2.2.0",
@@ -3522,7 +3562,6 @@
"url": "https://feross.org/support"
}
],
- "license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
@@ -4493,7 +4532,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
- "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -4508,7 +4546,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "license": "MIT",
"engines": {
"node": ">=0.8.x"
}
@@ -5118,10 +5155,9 @@
"license": "MIT"
},
"node_modules/gremlin": {
- "version": "3.7.4",
- "resolved": "https://registry.npmjs.org/gremlin/-/gremlin-3.7.4.tgz",
- "integrity": "sha512-BC/6q97uFcyJGjf1xVq0Uy5q06bJVbrb4KpAAOu8lfGV2RalGuvsIG7svlWatS/3q8b/HuwqHrMESVEDNBkBhw==",
- "license": "Apache-2.0",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/gremlin/-/gremlin-3.8.0.tgz",
+ "integrity": "sha512-VG4XhHZjqmJsVSrEKwYE3adW/G5jwQ5AoYWb3NUSV+sXRsdGHOvYLYzTIwax/CoyRHeL971vCO2jsdGJHIcuGQ==",
"dependencies": {
"buffer": "^6.0.3",
"eventemitter3": "^5.0.1",
@@ -5133,6 +5169,10 @@
"node": ">=20"
}
},
+ "node_modules/gremlin-language": {
+ "resolved": "../../../../gremlin-javascript/src/main/javascript/gremlin-javascript",
+ "link": true
+ },
"node_modules/gremlin/node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
@@ -5141,7 +5181,6 @@
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
- "license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
}
@@ -5297,8 +5336,7 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ],
- "license": "BSD-3-Clause"
+ ]
},
"node_modules/ignore": {
"version": "5.3.2",
@@ -7409,7 +7447,6 @@
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
- "license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
@@ -7523,7 +7560,6 @@
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
"integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
- "license": "MIT",
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
diff --git a/gremlin-test/build/generate-translator-data.groovy b/gremlin-test/build/generate-translator-data.groovy
new file mode 100644
index 0000000000..0ac881cbaa
--- /dev/null
+++ b/gremlin-test/build/generate-translator-data.groovy
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import groovy.json.JsonBuilder
+import org.apache.tinkerpop.gremlin.language.corpus.FeatureReader
+import org.apache.tinkerpop.gremlin.language.translator.GremlinTranslator
+import org.apache.tinkerpop.gremlin.language.translator.Translator
+import org.apache.tinkerpop.gremlin.language.translator.TranslatorException
+
+import java.nio.file.Paths
+
+// file is overwritten on each generation
+def outputFile = new File("${projectBaseDir}/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json")
+
+// assumes globally unique scenario names for keys with list of Gremlin traversals as they appear
+def gremlins = FeatureReader.parseGrouped(Paths.get("${projectBaseDir}", "gremlin-test", "src", "main", "resources", "org", "apache", "tinkerpop", "gremlin", "test", "features").toString())
+
+def scenarios = gremlins.collect { scenarioName, traversals ->
+ def translatedTraversals = traversals.collect { original ->
+ def entry = [original: original]
+ Translator.values().each { translator ->
+ try {
+ def language = translator.name().toLowerCase()
+ entry[language] = GremlinTranslator.translate(original, translator).getTranslated()
+ } catch (TranslatorException ignored) {
+ // entry[language] stays undefined/null
+ } catch (Exception ignored) {
+ // entry[language] stays undefined/null
+ }
+ }
+ return entry
+ }
+
+ return [scenario: scenarioName, traversals: translatedTraversals]
+}
+
+def json = new JsonBuilder(scenarios)
+outputFile.withWriter('UTF-8') { writer ->
+ writer.write(json.toPrettyString())
+}
diff --git a/gremlin-test/pom.xml b/gremlin-test/pom.xml
index ae98f9bd91..62ad88c75f 100644
--- a/gremlin-test/pom.xml
+++ b/gremlin-test/pom.xml
@@ -116,6 +116,56 @@ limitations under the License.
</testResource>
</testResources>
<plugins>
+ <plugin>
+ <groupId>org.codehaus.gmavenplus</groupId>
+ <artifactId>gmavenplus-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>${logback.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-all</artifactId>
+ <version>${groovy.version}</version>
+ <type>pom</type>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-json</artifactId>
+ <version>${groovy.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>generate-translator-data</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>execute</goal>
+ </goals>
+ <configuration>
+ <properties>
+ <property>
+ <name>projectBaseDir</name>
+ <value>${project.basedir}/../</value>
+ </property>
+ </properties>
+ <scripts>
+ <script>${project.basedir}/build/generate-translator-data.groovy</script>
+ </scripts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
new file mode 100644
index 0000000000..ff4d792054
--- /dev/null
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
@@ -0,0 +1,40985 @@
+[
+ {
+ "scenario": "g_V_branchXlabel_isXpersonX_countX_optionX1__ageX_optionX0__langX_optionX0__nameX",
+ "traversals": [
+ {
+ "original": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\"))",
+ "language": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\"))",
+ "anonymized": "g.V().branch(__.label().is(string0).count()).option(xx1, __.values(string1)).option(xx2, __.values(string2)).option(xx2, __.values(string3))",
+ "dotnet": "g.V().Branch<object>(__.Label().Is(\"person\").Count()).Option(xx1, __.Values<object>(\"age\")).Option(xx2, __.Values<object>(\"lang\")).Option(xx2, __.Values<object>(\"name\"))",
+ "go": "g.V().Branch(gremlingo.T__.Label().Is(\"person\").Count()).Option(xx1, gremlingo.T__.Values(\"age\")).Option(xx2, gremlingo.T__.Values(\"lang\")).Option(xx2, gremlingo.T__.Values(\"name\"))",
+ "groovy": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\"))",
+ "java": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\"))",
+ "javascript": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\"))",
+ "python": "g.V().branch(__.label().is_('person').count()).option(xx1, __.values('age')).option(xx2, __.values('lang')).option(xx2, __.values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_branchXlabel_isXpersonX_countX_optionX1__ageX_optionX0__langX_optionX0__nameX_optionXany__labelX",
+ "traversals": [
+ {
+ "original": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\")).option(Pick.any, __.label())",
+ "language": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\")).option(Pick.any, __.label())",
+ "anonymized": "g.V().branch(__.label().is(string0).count()).option(xx1, __.values(string1)).option(xx2, __.values(string2)).option(xx2, __.values(string3)).option(Pick.any, __.label())",
+ "dotnet": "g.V().Branch<object>(__.Label().Is(\"person\").Count()).Option(xx1, __.Values<object>(\"age\")).Option(xx2, __.Values<object>(\"lang\")).Option(xx2, __.Values<object>(\"name\")).Option(Pick.Any, __.Label())",
+ "go": "g.V().Branch(gremlingo.T__.Label().Is(\"person\").Count()).Option(xx1, gremlingo.T__.Values(\"age\")).Option(xx2, gremlingo.T__.Values(\"lang\")).Option(xx2, gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.Any, gremlingo.T__.Label())",
+ "groovy": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\")).option(Pick.any, __.label())",
+ "java": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\")).option(Pick.any, __.label())",
+ "javascript": "g.V().branch(__.label().is(\"person\").count()).option(xx1, __.values(\"age\")).option(xx2, __.values(\"lang\")).option(xx2, __.values(\"name\")).option(Pick.any, __.label())",
+ "python": "g.V().branch(__.label().is_('person').count()).option(xx1, __.values('age')).option(xx2, __.values('lang')).option(xx2, __.values('name')).option(Pick.any_, __.label())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_branchXageX_optionXltX30X__youngX_optionXgtX30X__oldX_optionXnone__on_the_edgeX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").branch(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gt(30), __.constant(\"old\")).option(Pick.none, __.constant(\"on the edge\"))",
+ "language": "g.V().hasLabel(\"person\").branch(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gt(30), __.constant(\"old\")).option(Pick.none, __.constant(\"on the edge\"))",
+ "anonymized": "g.V().hasLabel(string0).branch(__.values(string1)).option(P.lt(number0), __.constant(string2)).option(P.gt(number0), __.constant(string3)).option(Pick.none, __.constant(string4))",
+ "dotnet": "g.V().HasLabel(\"person\").Branch<object>(__.Values<object>(\"age\")).Option(P.Lt(30), __.Constant<object>(\"young\")).Option(P.Gt(30), __.Constant<object>(\"old\")).Option(Pick.None, __.Constant<object>(\"on the edge\"))",
+ "go": "g.V().HasLabel(\"person\").Branch(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Lt(30), gremlingo.T__.Constant(\"young\")).Option(gremlingo.P.Gt(30), gremlingo.T__.Constant(\"old\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"on the edge\"))",
+ "groovy": "g.V().hasLabel(\"person\").branch(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gt(30), __.constant(\"old\")).option(Pick.none, __.constant(\"on the edge\"))",
+ "java": "g.V().hasLabel(\"person\").branch(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gt(30), __.constant(\"old\")).option(Pick.none, __.constant(\"on the edge\"))",
+ "javascript": "g.V().hasLabel(\"person\").branch(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gt(30), __.constant(\"old\")).option(Pick.none, __.constant(\"on the edge\"))",
+ "python": "g.V().has_label('person').branch(__.values('age')).option(P.lt(30), __.constant('young')).option(P.gt(30), __.constant('old')).option(Pick.none, __.constant('on the edge'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_branchXidentityX_optionXhasLabelXsoftwareX__inXcreatedX_name_order_foldX_optionXhasXname_vadasX__ageX_optionXneqX123X__bothE_countX",
+ "traversals": [
+ {
+ "original": "g.V().branch(__.identity()).option(__.hasLabel(\"software\"), __.in(\"created\").values(\"name\").order().fold()).option(__.has(\"name\",\"vadas\"), __.values(\"age\")).option(P.neq(123), __.bothE().count())",
+ "language": "g.V().branch(__.identity()).option(__.hasLabel(\"software\"), __.in(\"created\").values(\"name\").order().fold()).option(__.has(\"name\", \"vadas\"), __.values(\"age\")).option(P.neq(123), __.bothE().count())",
+ "anonymized": "g.V().branch(__.identity()).option(__.hasLabel(string0), __.in(string1).values(string2).order().fold()).option(__.has(string2, string3), __.values(string4)).option(P.neq(number0), __.bothE().count())",
+ "dotnet": "g.V().Branch<object>(__.Identity()).Option(__.HasLabel(\"software\"), __.In(\"created\").Values<object>(\"name\").Order().Fold()).Option(__.Has(\"name\", \"vadas\"), __.Values<object>(\"age\")).Option(P.Neq(123), __.BothE().Count())",
+ "go": "g.V().Branch(gremlingo.T__.Identity()).Option(gremlingo.T__.HasLabel(\"software\"), gremlingo.T__.In(\"created\").Values(\"name\").Order().Fold()).Option(gremlingo.T__.Has(\"name\", \"vadas\"), gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Neq(123), gremlingo.T__.BothE().Count())",
+ "groovy": "g.V().branch(__.identity()).option(__.hasLabel(\"software\"), __.in(\"created\").values(\"name\").order().fold()).option(__.has(\"name\", \"vadas\"), __.values(\"age\")).option(P.neq(123), __.bothE().count())",
+ "java": "g.V().branch(__.identity()).option(__.hasLabel(\"software\"), __.in(\"created\").values(\"name\").order().fold()).option(__.has(\"name\", \"vadas\"), __.values(\"age\")).option(P.neq(123), __.bothE().count())",
+ "javascript": "g.V().branch(__.identity()).option(__.hasLabel(\"software\"), __.in_(\"created\").values(\"name\").order().fold()).option(__.has(\"name\", \"vadas\"), __.values(\"age\")).option(P.neq(123), __.bothE().count())",
+ "python": "g.V().branch(__.identity()).option(__.has_label('software'), __.in_('created').values('name').order().fold()).option(__.has('name', 'vadas'), __.values('age')).option(P.neq(123), __.both_e().count())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXout_countX_optionX2L_nameX_optionX3L_ageX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\"))",
+ "language": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\"))",
+ "anonymized": "g.V().choose(__.out().count()).option(xx1, __.values(string0)).option(xx2, __.values(string1))",
+ "dotnet": "g.V().Choose<object>(__.Out().Count()).Option(xx1, __.Values<object>(\"name\")).Option(xx2, __.Values<object>(\"age\"))",
+ "go": "g.V().Choose(gremlingo.T__.Out().Count()).Option(xx1, gremlingo.T__.Values(\"name\")).Option(xx2, gremlingo.T__.Values(\"age\"))",
+ "groovy": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\"))",
+ "java": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\"))",
+ "javascript": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\"))",
+ "python": "g.V().choose(__.out().count()).option(xx1, __.values('name')).option(xx2, __.values('age'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXout_countX_optionX2L_nameX_optionX3L_ageX_optionXnone_discardX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\")).option(Pick.none, __.discard())",
+ "language": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\")).option(Pick.none, __.discard())",
+ "anonymized": "g.V().choose(__.out().count()).option(xx1, __.values(string0)).option(xx2, __.values(string1)).option(Pick.none, __.discard())",
+ "dotnet": "g.V().Choose<object>(__.Out().Count()).Option(xx1, __.Values<object>(\"name\")).Option(xx2, __.Values<object>(\"age\")).Option(Pick.None, __.Discard())",
+ "go": "g.V().Choose(gremlingo.T__.Out().Count()).Option(xx1, gremlingo.T__.Values(\"name\")).Option(xx2, gremlingo.T__.Values(\"age\")).Option(gremlingo.Pick.None, gremlingo.T__.Discard())",
+ "groovy": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\")).option(Pick.none, __.discard())",
+ "java": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\")).option(Pick.none, __.discard())",
+ "javascript": "g.V().choose(__.out().count()).option(xx1, __.values(\"name\")).option(xx2, __.values(\"age\")).option(Pick.none, __.discard())",
+ "python": "g.V().choose(__.out().count()).option(xx1, __.values('name')).option(xx2, __.values('age')).option(Pick.none, __.discard())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasLabelXpersonX_and_outXcreatedX__outXknowsX_identityX_name",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"),__.out(\"knows\"),__.identity()).values(\"name\")",
+ "language": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\"), __.identity()).values(\"name\")",
+ "anonymized": "g.V().choose(__.hasLabel(string0).and().out(string1), __.out(string2), __.identity()).values(string3)",
+ "dotnet": "g.V().Choose<object>(__.HasLabel(\"person\").And().Out(\"created\"), __.Out(\"knows\"), __.Identity()).Values<object>(\"name\")",
+ "go": "g.V().Choose(gremlingo.T__.HasLabel(\"person\").And().Out(\"created\"), gremlingo.T__.Out(\"knows\"), gremlingo.T__.Identity()).Values(\"name\")",
+ "groovy": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\"), __.identity()).values(\"name\")",
+ "java": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\"), __.identity()).values(\"name\")",
+ "javascript": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\"), __.identity()).values(\"name\")",
+ "python": "g.V().choose(__.has_label('person').and_().out('created'), __.out('knows'), __.identity()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasLabelXpersonX_and_outXcreatedX_outXknowsX_name",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"),__.out(\"knows\")).values(\"name\")",
+ "language": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\")).values(\"name\")",
+ "anonymized": "g.V().choose(__.hasLabel(string0).and().out(string1), __.out(string2)).values(string3)",
+ "dotnet": "g.V().Choose<object>(__.HasLabel(\"person\").And().Out(\"created\"), __.Out(\"knows\")).Values<object>(\"name\")",
+ "go": "g.V().Choose(gremlingo.T__.HasLabel(\"person\").And().Out(\"created\"), gremlingo.T__.Out(\"knows\")).Values(\"name\")",
+ "groovy": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\")).values(\"name\")",
+ "java": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\")).values(\"name\")",
+ "javascript": "g.V().choose(__.hasLabel(\"person\").and().out(\"created\"), __.out(\"knows\")).values(\"name\")",
+ "python": "g.V().choose(__.has_label('person').and_().out('created'), __.out('knows')).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXlabelX_optionXblah__outXknowsXX_optionXbleep__outXcreatedXX_optionXnone__identityX_name",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.label()).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "language": "g.V().choose(__.label()).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "anonymized": "g.V().choose(__.label()).option(string0, __.out(string1)).option(string2, __.out(string3)).option(Pick.none, __.identity()).values(string4)",
+ "dotnet": "g.V().Choose<object>(__.Label()).Option(\"blah\", __.Out(\"knows\")).Option(\"bleep\", __.Out(\"created\")).Option(Pick.None, __.Identity()).Values<object>(\"name\")",
+ "go": "g.V().Choose(gremlingo.T__.Label()).Option(\"blah\", gremlingo.T__.Out(\"knows\")).Option(\"bleep\", gremlingo.T__.Out(\"created\")).Option(gremlingo.Pick.None, gremlingo.T__.Identity()).Values(\"name\")",
+ "groovy": "g.V().choose(__.label()).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "java": "g.V().choose(__.label()).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "javascript": "g.V().choose(__.label()).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "python": "g.V().choose(__.label()).option('blah', __.out('knows')).option('bleep', __.out('created')).option(Pick.none, __.identity()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXTlabelX_optionXperson__outXknowsX_nameX_optionXbleep_constantXbleepXX",
+ "traversals": [
+ {
+ "original": "g.V().choose(T.label).option(\"person\", __.out(\"knows\").values(\"name\")).option(\"bleep\", __.constant(\"bleep\"))",
+ "language": "g.V().choose(T.label).option(\"person\", __.out(\"knows\").values(\"name\")).option(\"bleep\", __.constant(\"bleep\"))",
+ "anonymized": "g.V().choose(T.label).option(string0, __.out(string1).values(string2)).option(string3, __.constant(string3))",
+ "dotnet": "g.V().Choose<object>(T.Label).Option(\"person\", __.Out(\"knows\").Values<object>(\"name\")).Option(\"bleep\", __.Constant<object>(\"bleep\"))",
+ "go": "g.V().Choose(gremlingo.T.Label).Option(\"person\", gremlingo.T__.Out(\"knows\").Values(\"name\")).Option(\"bleep\", gremlingo.T__.Constant(\"bleep\"))",
+ "groovy": "g.V().choose(T.label).option(\"person\", __.out(\"knows\").values(\"name\")).option(\"bleep\", __.constant(\"bleep\"))",
+ "java": "g.V().choose(T.label).option(\"person\", __.out(\"knows\").values(\"name\")).option(\"bleep\", __.constant(\"bleep\"))",
+ "javascript": "g.V().choose(T.label).option(\"person\", __.out(\"knows\").values(\"name\")).option(\"bleep\", __.constant(\"bleep\"))",
+ "python": "g.V().choose(T.label).option('person', __.out('knows').values('name')).option('bleep', __.constant('bleep'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXTlabelX_optionXblah__outXknowsXX_optionXbleep__outXcreatedXX_optionXnone__identityX_name",
+ "traversals": [
+ {
+ "original": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "language": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "anonymized": "g.V().choose(T.label).option(string0, __.out(string1)).option(string2, __.out(string3)).option(Pick.none, __.identity()).values(string4)",
+ "dotnet": "g.V().Choose<object>(T.Label).Option(\"blah\", __.Out(\"knows\")).Option(\"bleep\", __.Out(\"created\")).Option(Pick.None, __.Identity()).Values<object>(\"name\")",
+ "go": "g.V().Choose(gremlingo.T.Label).Option(\"blah\", gremlingo.T__.Out(\"knows\")).Option(\"bleep\", gremlingo.T__.Out(\"created\")).Option(gremlingo.Pick.None, gremlingo.T__.Identity()).Values(\"name\")",
+ "groovy": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "java": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "javascript": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.identity()).values(\"name\")",
+ "python": "g.V().choose(T.label).option('blah', __.out('knows')).option('bleep', __.out('created')).option(Pick.none, __.identity()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXTlabelX_optionXblah__outXknowsXX_optionXbleep__outXcreatedXX_optionXnone_discardX_name",
+ "traversals": [
+ {
+ "original": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.discard()).values(\"name\")",
+ "language": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.discard()).values(\"name\")",
+ "anonymized": "g.V().choose(T.label).option(string0, __.out(string1)).option(string2, __.out(string3)).option(Pick.none, __.discard()).values(string4)",
+ "dotnet": "g.V().Choose<object>(T.Label).Option(\"blah\", __.Out(\"knows\")).Option(\"bleep\", __.Out(\"created\")).Option(Pick.None, __.Discard()).Values<object>(\"name\")",
+ "go": "g.V().Choose(gremlingo.T.Label).Option(\"blah\", gremlingo.T__.Out(\"knows\")).Option(\"bleep\", gremlingo.T__.Out(\"created\")).Option(gremlingo.Pick.None, gremlingo.T__.Discard()).Values(\"name\")",
+ "groovy": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.discard()).values(\"name\")",
+ "java": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.discard()).values(\"name\")",
+ "javascript": "g.V().choose(T.label).option(\"blah\", __.out(\"knows\")).option(\"bleep\", __.out(\"created\")).option(Pick.none, __.discard()).values(\"name\")",
+ "python": "g.V().choose(T.label).option('blah', __.out('knows')).option('bleep', __.out('created')).option(Pick.none, __.discard()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXoutXknowsX_count_isXgtX0XX__outXknowsXX_name",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.out(\"knows\").count().is(P.gt(0)),__.out(\"knows\")).values(\"name\")",
+ "language": "g.V().choose(__.out(\"knows\").count().is(P.gt(0)), __.out(\"knows\")).values(\"name\")",
+ "anonymized": "g.V().choose(__.out(string0).count().is(P.gt(number0)), __.out(string0)).values(string1)",
+ "dotnet": "g.V().Choose<object>(__.Out(\"knows\").Count().Is(P.Gt(0)), __.Out(\"knows\")).Values<object>(\"name\")",
+ "go": "g.V().Choose(gremlingo.T__.Out(\"knows\").Count().Is(gremlingo.P.Gt(0)), gremlingo.T__.Out(\"knows\")).Values(\"name\")",
+ "groovy": "g.V().choose(__.out(\"knows\").count().is(P.gt(0)), __.out(\"knows\")).values(\"name\")",
+ "java": "g.V().choose(__.out(\"knows\").count().is(P.gt(0)), __.out(\"knows\")).values(\"name\")",
+ "javascript": "g.V().choose(__.out(\"knows\").count().is(P.gt(0)), __.out(\"knows\")).values(\"name\")",
+ "python": "g.V().choose(__.out('knows').count().is_(P.gt(0)), __.out('knows')).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_asXp1X_chooseXoutEXknowsX__outXknowsXX_asXp2X_selectXp1_p2X_byXnameX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").as(\"p1\").choose(__.outE(\"knows\"), __.out(\"knows\")).as(\"p2\").select(\"p1\", \"p2\").by(\"name\")",
+ "language": "g.V().hasLabel(\"person\").as(\"p1\").choose(__.outE(\"knows\"), __.out(\"knows\")).as(\"p2\").select(\"p1\", \"p2\").by(\"name\")",
+ "anonymized": "g.V().hasLabel(string0).as(string1).choose(__.outE(string2), __.out(string2)).as(string3).select(string1, string3).by(string4)",
+ "dotnet": "g.V().HasLabel(\"person\").As(\"p1\").Choose<object>(__.OutE(\"knows\"), __.Out(\"knows\")).As(\"p2\").Select<object>(\"p1\", \"p2\").By(\"name\")",
+ "go": "g.V().HasLabel(\"person\").As(\"p1\").Choose(gremlingo.T__.OutE(\"knows\"), gremlingo.T__.Out(\"knows\")).As(\"p2\").Select(\"p1\", \"p2\").By(\"name\")",
+ "groovy": "g.V().hasLabel(\"person\").as(\"p1\").choose(__.outE(\"knows\"), __.out(\"knows\")).as(\"p2\").select(\"p1\", \"p2\").by(\"name\")",
+ "java": "g.V().hasLabel(\"person\").as(\"p1\").choose(__.outE(\"knows\"), __.out(\"knows\")).as(\"p2\").select(\"p1\", \"p2\").by(\"name\")",
+ "javascript": "g.V().hasLabel(\"person\").as(\"p1\").choose(__.outE(\"knows\"), __.out(\"knows\")).as(\"p2\").select(\"p1\", \"p2\").by(\"name\")",
+ "python": "g.V().has_label('person').as_('p1').choose(__.out_e('knows'), __.out('knows')).as_('p2').select('p1', 'p2').by('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseXageX__optionX27L__constantXyoungXX_optionXnone__constantXoldXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(xx1, __.constant(\"young\")).option(Pick.none, __.constant(\"old\")).groupCount()",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(xx1, __.constant(\"young\")).option(Pick.none, __.constant(\"old\")).groupCount()",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1)).option(xx1, __.constant(string2)).option(Pick.none, __.constant(string3)).groupCount()",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"age\")).Option(xx1, __.Constant<object>(\"young\")).Option(Pick.None, __.Constant<object>(\"old\")).GroupCount<object>()",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"age\")).Option(xx1, gremlingo.T__.Constant(\"young\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"old\")).GroupCount()",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(xx1, __.constant(\"young\")).option(Pick.none, __.constant(\"old\")).groupCount()",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(xx1, __.constant(\"young\")).option(Pick.none, __.constant(\"old\")).groupCount()",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(xx1, __.constant(\"young\")).option(Pick.none, __.constant(\"old\")).groupCount()",
+ "python": "g.V().has_label('person').choose(__.values('age')).option(xx1, __.constant('young')).option(Pick.none, __.constant('old')).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectX1X_chooseXisX1X__constantX10Xfold__foldX",
+ "traversals": [
+ {
+ "original": "g.inject(1i).choose(__.is(xx1), __.constant(10i).fold(), __.fold())",
+ "language": "g.inject(1i).choose(__.is(xx1), __.constant(10i).fold(), __.fold())",
+ "anonymized": "g.inject(integer0).choose(__.is(xx1), __.constant(integer1).fold(), __.fold())",
+ "dotnet": "g.Inject<object>(1).Choose<object>(__.Is(xx1), __.Constant<object>(10).Fold(), __.Fold<object>())",
+ "go": "g.Inject(int32(1)).Choose(gremlingo.T__.Is(xx1), gremlingo.T__.Constant(int32(10)).Fold(), gremlingo.T__.Fold())",
+ "groovy": "g.inject(1i).choose(__.is(xx1), __.constant(10i).fold(), __.fold())",
+ "java": "g.inject(1).choose(__.is(xx1), __.constant(10).fold(), __.fold())",
+ "javascript": "g.inject(1).choose(__.is(xx1), __.constant(10).fold(), __.fold())",
+ "python": "g.inject(1).choose(__.is_(xx1), __.constant(10).fold(), __.fold())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectX2X_chooseXisX1X__constantX10Xfold__foldX",
+ "traversals": [
+ {
+ "original": "g.inject(2i).choose(__.is(xx1), __.constant(10i).fold(), __.fold())",
+ "language": "g.inject(2i).choose(__.is(xx1), __.constant(10i).fold(), __.fold())",
+ "anonymized": "g.inject(integer0).choose(__.is(xx1), __.constant(integer1).fold(), __.fold())",
+ "dotnet": "g.Inject<object>(2).Choose<object>(__.Is(xx1), __.Constant<object>(10).Fold(), __.Fold<object>())",
+ "go": "g.Inject(int32(2)).Choose(gremlingo.T__.Is(xx1), gremlingo.T__.Constant(int32(10)).Fold(), gremlingo.T__.Fold())",
+ "groovy": "g.inject(2i).choose(__.is(xx1), __.constant(10i).fold(), __.fold())",
+ "java": "g.inject(2).choose(__.is(xx1), __.constant(10).fold(), __.fold())",
+ "javascript": "g.inject(2).choose(__.is(xx1), __.constant(10).fold(), __.fold())",
+ "python": "g.inject(2).choose(__.is_(xx1), __.constant(10).fold(), __.fold())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasLabelXpersonX_chooseXageX_optionXbetweenX26_30X_constantXxXX_optionXbetweenX20_30X_constantXyXX_optionXnone_constantXzXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.constant(\"x\")).option(P.between(20, 30), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.constant(\"x\")).option(P.between(20, 30), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1)).option(P.between(number0, number1), __.constant(string2)).option(P.between(number2, number1), __.constant(string3)).option(Pick.none, __.constant(string4))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Constant<object>(\"x\")).Option(P.Between(20, 30), __.Constant<object>(\"y\")).Option(Pick.None, __.Constant<object>(\"z\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Constant(\"x\")).Option(gremlingo.P.Between(20, 30), gremlingo.T__.Constant(\"y\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"z\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.constant(\"x\")).option(P.between(20, 30), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.constant(\"x\")).option(P.between(20, 30), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.constant(\"x\")).option(P.between(20, 30), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "python": "g.V().has_label('person').choose(__.values('age')).option(P.between(26, 30), __.constant('x')).option(P.between(20, 30), __.constant('y')).option(Pick.none, __.constant('z'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasLabelXpersonX_chooseXageX_optionXbetweenX26_30X_orXgtX34XX_constantXxXX_optionXgtX34X_constantXyXX_optionXnone_constantXzXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30).or(P.gt(34)), __.constant(\"x\")).option(P.gt(34), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30).or(P.gt(34)), __.constant(\"x\")).option(P.gt(34), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1)).option(P.between(number0, number1).or(P.gt(number2)), __.constant(string2)).option(P.gt(number2), __.constant(string3)).option(Pick.none, __.constant(string4))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30).Or(P.Gt(34)), __.Constant<object>(\"x\")).Option(P.Gt(34), __.Constant<object>(\"y\")).Option(Pick.None, __.Constant<object>(\"z\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30).Or(gremlingo.P.Gt(34)), gremlingo.T__.Constant(\"x\")).Option(gremlingo.P.Gt(34), gremlingo.T__.Constant(\"y\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"z\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30).or(P.gt(34)), __.constant(\"x\")).option(P.gt(34), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30).or(P.gt(34)), __.constant(\"x\")).option(P.gt(34), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30).or(P.gt(34)), __.constant(\"x\")).option(P.gt(34), __.constant(\"y\")).option(Pick.none, __.constant(\"z\"))",
+ "python": "g.V().has_label('person').choose(__.values('age')).option(P.between(26, 30).or_(P.gt(34)), __.constant('x')).option(P.gt(34), __.constant('y')).option(Pick.none, __.constant('z'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseXageX_optionXbetweenX26_30X_nameX_optionXnone_nameX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1)).option(P.between(number0, number1), __.values(string2)).option(Pick.none, __.values(string2))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\")).Option(Pick.None, __.Values<object>(\"name\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "python": "g.V().has_label('person').choose(__.values('age')).option(P.between(26, 30), __.values('name')).option(Pick.none, __.values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasLabelXpersonX_localXchooseXageX_optionXbetweenX26_30X_name_foldX_optionXnone_name_foldXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "language": "g.V().hasLabel(\"person\").local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "anonymized": "g.V().hasLabel(string0).local(__.choose(__.values(string1)).option(P.between(number0, number1), __.values(string2).fold()).option(Pick.none, __.values(string2).fold()))",
+ "dotnet": "g.V().HasLabel(\"person\").Local<object>(__.Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\").Fold()).Option(Pick.None, __.Values<object>(\"name\").Fold()))",
+ "go": "g.V().HasLabel(\"person\").Local(gremlingo.T__.Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\").Fold()).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\").Fold()))",
+ "groovy": "g.V().hasLabel(\"person\").local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "java": "g.V().hasLabel(\"person\").local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "javascript": "g.V().hasLabel(\"person\").local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "python": "g.V().has_label('person').local(__.choose(__.values('age')).option(P.between(26, 30), __.values('name').fold()).option(Pick.none, __.values('name').fold()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasLabelXpersonX_mapXchooseXageX_optionXbetweenX26_30X_name_foldX_optionXnone_name_foldXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "language": "g.V().hasLabel(\"person\").map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "anonymized": "g.V().hasLabel(string0).map(__.choose(__.values(string1)).option(P.between(number0, number1), __.values(string2).fold()).option(Pick.none, __.values(string2).fold()))",
+ "dotnet": "g.V().HasLabel(\"person\").Map<object>(__.Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\").Fold()).Option(Pick.None, __.Values<object>(\"name\").Fold()))",
+ "go": "g.V().HasLabel(\"person\").Map(gremlingo.T__.Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\").Fold()).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\").Fold()))",
+ "groovy": "g.V().hasLabel(\"person\").map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "java": "g.V().hasLabel(\"person\").map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "javascript": "g.V().hasLabel(\"person\").map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "python": "g.V().has_label('person').map(__.choose(__.values('age')).option(P.between(26, 30), __.values('name').fold()).option(Pick.none, __.values('name').fold()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXV_VXhasLabelXpersonX_barrier_localXchooseXageX_optionXbetweenX26_30X_name_foldX_optionXnone_name_foldXX",
+ "traversals": [
+ {
+ "original": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "language": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "anonymized": "g.union(__.V(), __.V()).hasLabel(string0).barrier().local(__.choose(__.values(string1)).option(P.between(number0, number1), __.values(string2).fold()).option(Pick.none, __.values(string2).fold()))",
+ "dotnet": "g.Union<object>(__.V(), __.V()).HasLabel(\"person\").Barrier().Local<object>(__.Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\").Fold()).Option(Pick.None, __.Values<object>(\"name\").Fold()))",
+ "go": "g.Union(gremlingo.T__.V(), gremlingo.T__.V()).HasLabel(\"person\").Barrier().Local(gremlingo.T__.Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\").Fold()).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\").Fold()))",
+ "groovy": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "java": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "javascript": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().local(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "python": "g.union(__.V(), __.V()).has_label('person').barrier().local(__.choose(__.values('age')).option(P.between(26, 30), __.values('name').fold()).option(Pick.none, __.values('name').fold()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXV_VXhasLabelXpersonX_barrier_mapXchooseXageX_optionXbetweenX26_30X_name_foldX_optionXnone_name_foldXX",
+ "traversals": [
+ {
+ "original": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "language": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "anonymized": "g.union(__.V(), __.V()).hasLabel(string0).barrier().map(__.choose(__.values(string1)).option(P.between(number0, number1), __.values(string2).fold()).option(Pick.none, __.values(string2).fold()))",
+ "dotnet": "g.Union<object>(__.V(), __.V()).HasLabel(\"person\").Barrier().Map<object>(__.Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\").Fold()).Option(Pick.None, __.Values<object>(\"name\").Fold()))",
+ "go": "g.Union(gremlingo.T__.V(), gremlingo.T__.V()).HasLabel(\"person\").Barrier().Map(gremlingo.T__.Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\").Fold()).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\").Fold()))",
+ "groovy": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "java": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "javascript": "g.union(__.V(), __.V()).hasLabel(\"person\").barrier().map(__.choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\").fold()).option(Pick.none, __.values(\"name\").fold()))",
+ "python": "g.union(__.V(), __.V()).has_label('person').barrier().map(__.choose(__.values('age')).option(P.between(26, 30), __.values('name').fold()).option(Pick.none, __.values('name').fold()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXageX_optionXbetweenX26_30X_nameX_optionXnone_nameX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "language": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "anonymized": "g.V().choose(__.values(string0)).option(P.between(number0, number1), __.values(string1)).option(Pick.none, __.values(string1))",
+ "dotnet": "g.V().Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\")).Option(Pick.None, __.Values<object>(\"name\"))",
+ "go": "g.V().Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\"))",
+ "groovy": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "java": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "javascript": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\"))",
+ "python": "g.V().choose(__.values('age')).option(P.between(26, 30), __.values('name')).option(Pick.none, __.values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXageX_optionXbetweenX26_30X_nameX_optionXnone_nameX_optionXunproductive_labelX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.unproductive, __.label())",
+ "language": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.unproductive, __.label())",
+ "anonymized": "g.V().choose(__.values(string0)).option(P.between(number0, number1), __.values(string1)).option(Pick.none, __.values(string1)).option(Pick.unproductive, __.label())",
+ "dotnet": "g.V().Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\")).Option(Pick.None, __.Values<object>(\"name\")).Option(Pick.Unproductive, __.Label())",
+ "go": "g.V().Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.Unproductive, gremlingo.T__.Label())",
+ "groovy": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.unproductive, __.label())",
+ "java": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.unproductive, __.label())",
+ "javascript": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.unproductive, __.label())",
+ "python": "g.V().choose(__.values('age')).option(P.between(26, 30), __.values('name')).option(Pick.none, __.values('name')).option(Pick.unproductive, __.label())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXageX_optionXbetweenX26_30X_nameX_optionXnone_nameX_optionXnone_identityX_optionXnone_failX_optionXunproductive_identityX_optionXunproductive_labelX_optionXnone_failX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.none, __.identity()).option(Pick.none, __.fail()).option(Pick.unproductive, __.label()).option(Pick.unproductive, __.identity()).option(Pick.unproductive, __.fail())",
+ "language": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.none, __.identity()).option(Pick.none, __.fail()).option(Pick.unproductive, __.label()).option(Pick.unproductive, __.identity()).option(Pick.unproductive, __.fail())",
+ "anonymized": "g.V().choose(__.values(string0)).option(P.between(number0, number1), __.values(string1)).option(Pick.none, __.values(string1)).option(Pick.none, __.identity()).option(Pick.none, __.fail()).option(Pick.unproductive, __.label()).option(Pick.unproductive, __.identity()).option(Pick.unproductive, __.fail())",
+ "dotnet": "g.V().Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\")).Option(Pick.None, __.Values<object>(\"name\")).Option(Pick.None, __.Identity()).Option(Pick.None, __.Fail()).Option(Pick.Unproductive, __.Label()).Option(Pick.Unproductive, __.Identity()).Option(Pick.Unproductive, __.Fail())",
+ "go": "g.V().Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.None, gremlingo.T__.Identity()).Option(gremlingo.Pick.None, gremlingo.T__.Fail()).Option(gremlingo.Pick.Unproductive, gremlingo.T__.Label()).Option(gremlingo.Pick.Unproductive, gremlingo.T__.Identity()).Option(gremlingo.Pick.Unproductive, gremlingo.T__.Fail())",
+ "groovy": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.none, __.identity()).option(Pick.none, __.fail()).option(Pick.unproductive, __.label()).option(Pick.unproductive, __.identity()).option(Pick.unproductive, __.fail())",
+ "java": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.none, __.identity()).option(Pick.none, __.fail()).option(Pick.unproductive, __.label()).option(Pick.unproductive, __.identity()).option(Pick.unproductive, __.fail())",
+ "javascript": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.values(\"name\")).option(Pick.none, __.identity()).option(Pick.none, __.fail()).option(Pick.unproductive, __.label()).option(Pick.unproductive, __.identity()).option(Pick.unproductive, __.fail())",
+ "python": "g.V().choose(__.values('age')).option(P.between(26, 30), __.values('name')).option(Pick.none, __.values('name')).option(Pick.none, __.identity()).option(Pick.none, __.fail()).option(Pick.unproductive, __.label()).option(Pick.unproductive, __.identity()).option(Pick.unproductive, __.fail())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXage_nameX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.values(\"age\"), __.values(\"name\"))",
+ "language": "g.V().choose(__.values(\"age\"), __.values(\"name\"))",
+ "anonymized": "g.V().choose(__.values(string0), __.values(string1))",
+ "dotnet": "g.V().Choose<object>(__.Values<object>(\"age\"), __.Values<object>(\"name\"))",
+ "go": "g.V().Choose(gremlingo.T__.Values(\"age\"), gremlingo.T__.Values(\"name\"))",
+ "groovy": "g.V().choose(__.values(\"age\"), __.values(\"name\"))",
+ "java": "g.V().choose(__.values(\"age\"), __.values(\"name\"))",
+ "javascript": "g.V().choose(__.values(\"age\"), __.values(\"name\"))",
+ "python": "g.V().choose(__.values('age'), __.values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXageX_optionXbetweenX26_30X_nameX_optionXnone_discardX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.discard())",
+ "language": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.discard())",
+ "anonymized": "g.V().choose(__.values(string0)).option(P.between(number0, number1), __.values(string1)).option(Pick.none, __.discard())",
+ "dotnet": "g.V().Choose<object>(__.Values<object>(\"age\")).Option(P.Between(26, 30), __.Values<object>(\"name\")).Option(Pick.None, __.Discard())",
+ "go": "g.V().Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Between(26, 30), gremlingo.T__.Values(\"name\")).Option(gremlingo.Pick.None, gremlingo.T__.Discard())",
+ "groovy": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.discard())",
+ "java": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.discard())",
+ "javascript": "g.V().choose(__.values(\"age\")).option(P.between(26, 30), __.values(\"name\")).option(Pick.none, __.discard())",
+ "python": "g.V().choose(__.values('age')).option(P.between(26, 30), __.values('name')).option(Pick.none, __.discard())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXnameX_optionXneqXyX_ageX_optionXnone_constantXxXX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.values(\"name\")).option(P.neq(\"y\"), __.values(\"age\")).option(Pick.none, __.constant(\"x\"))",
+ "language": "g.V().choose(__.values(\"name\")).option(P.neq(\"y\"), __.values(\"age\")).option(Pick.none, __.constant(\"x\"))",
+ "anonymized": "g.V().choose(__.values(string0)).option(P.neq(string1), __.values(string2)).option(Pick.none, __.constant(string3))",
+ "dotnet": "g.V().Choose<object>(__.Values<object>(\"name\")).Option(P.Neq(\"y\"), __.Values<object>(\"age\")).Option(Pick.None, __.Constant<object>(\"x\"))",
+ "go": "g.V().Choose(gremlingo.T__.Values(\"name\")).Option(gremlingo.P.Neq(\"y\"), gremlingo.T__.Values(\"age\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"x\"))",
+ "groovy": "g.V().choose(__.values(\"name\")).option(P.neq(\"y\"), __.values(\"age\")).option(Pick.none, __.constant(\"x\"))",
+ "java": "g.V().choose(__.values(\"name\")).option(P.neq(\"y\"), __.values(\"age\")).option(Pick.none, __.constant(\"x\"))",
+ "javascript": "g.V().choose(__.values(\"name\")).option(P.neq(\"y\"), __.values(\"age\")).option(Pick.none, __.constant(\"x\"))",
+ "python": "g.V().choose(__.values('name')).option(P.neq('y'), __.values('age')).option(Pick.none, __.constant('x'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseXoutXcreatedX_count_isXeqX0XX__constantXdidnt_createX__constantXcreatedXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count().is(P.eq(0)),__.constant(\"didnt_create\"),__.constant(\"created\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count().is(P.eq(0)), __.constant(\"didnt_create\"), __.constant(\"created\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.out(string1).count().is(P.eq(number0)), __.constant(string2), __.constant(string1))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Out(\"created\").Count().Is(P.Eq(0)), __.Constant<object>(\"didnt_create\"), __.Constant<object>(\"created\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Out(\"created\").Count().Is(gremlingo.P.Eq(0)), gremlingo.T__.Constant(\"didnt_create\"), gremlingo.T__.Constant(\"created\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count().is(P.eq(0)), __.constant(\"didnt_create\"), __.constant(\"created\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count().is(P.eq(0)), __.constant(\"didnt_create\"), __.constant(\"created\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count().is(P.eq(0)), __.constant(\"didnt_create\"), __.constant(\"created\"))",
+ "python": "g.V().has_label('person').choose(__.out('created').count().is_(P.eq(0)), __.constant('didnt_create'), __.constant('created'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseXvaluesXageX_isXgtX30XX__valuesXageX__constantX30XX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(30)),__.values(\"age\"),__.constant(30))",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(30)), __.values(\"age\"), __.constant(30))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1).is(P.gt(number0)), __.values(string1), __.constant(number0))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"age\").Is(P.Gt(30)), __.Values<object>(\"age\"), __.Constant<object>(30))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"age\").Is(gremlingo.P.Gt(30)), gremlingo.T__.Values(\"age\"), gremlingo.T__.Constant(30))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(30)), __.values(\"age\"), __.constant(30))",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(30)), __.values(\"age\"), __.constant(30))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(30)), __.values(\"age\"), __.constant(30))",
+ "python": "g.V().has_label('person').choose(__.values('age').is_(P.gt(30)), __.values('age'), __.constant(30))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseXvaluesXageX_isXgtX29XX_and_valuesXageX_isXltX35XX__valuesXnameX__constantXotherXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(29)).and().values(\"age\").is(P.lt(35)),__.values(\"name\"),__.constant(\"other\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(29)).and().values(\"age\").is(P.lt(35)), __.values(\"name\"), __.constant(\"other\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1).is(P.gt(number0)).and().values(string1).is(P.lt(number1)), __.values(string2), __.constant(string3))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"age\").Is(P.Gt(29)).And().Values<object>(\"age\").Is(P.Lt(35)), __.Values<object>(\"name\"), __.Constant<object>(\"other\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"age\").Is(gremlingo.P.Gt(29)).And().Values(\"age\").Is(gremlingo.P.Lt(35)), gremlingo.T__.Values(\"name\"), gremlingo.T__.Constant(\"other\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(29)).and().values(\"age\").is(P.lt(35)), __.values(\"name\"), __.constant(\"other\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(29)).and().values(\"age\").is(P.lt(35)), __.values(\"name\"), __.constant(\"other\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"age\").is(P.gt(29)).and().values(\"age\").is(P.lt(35)), __.values(\"name\"), __.constant(\"other\"))",
+ "python": "g.V().has_label('person').choose(__.values('age').is_(P.gt(29)).and_().values('age').is_(P.lt(35)), __.values('name'), __.constant('other'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasXname_vadasX__valuesXnameX__valuesXageXX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.has(\"name\", \"vadas\"),__.values(\"name\"),__.values(\"age\"))",
+ "language": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"), __.values(\"age\"))",
+ "anonymized": "g.V().choose(__.has(string0, string1), __.values(string0), __.values(string2))",
+ "dotnet": "g.V().Choose<object>(__.Has(\"name\", \"vadas\"), __.Values<object>(\"name\"), __.Values<object>(\"age\"))",
+ "go": "g.V().Choose(gremlingo.T__.Has(\"name\", \"vadas\"), gremlingo.T__.Values(\"name\"), gremlingo.T__.Values(\"age\"))",
+ "groovy": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"), __.values(\"age\"))",
+ "java": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"), __.values(\"age\"))",
+ "javascript": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"), __.values(\"age\"))",
+ "python": "g.V().choose(__.has('name', 'vadas'), __.values('name'), __.values('age'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseXoutXcreatedX_countX_optionX0__constantXnoneXX_optionX1__constantXoneXX_optionX2__constantXmanyXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count()).option(xx0, __.constant(\"none\")).option(xx1, __.constant(\"one\")).option(xx2, __.constant(\"many\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count()).option(xx0, __.constant(\"none\")).option(xx1, __.constant(\"one\")).option(xx2, __.constant(\"many\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.out(string1).count()).option(xx0, __.constant(string2)).option(xx1, __.constant(string3)).option(xx2, __.constant(string4))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Out(\"created\").Count()).Option(xx0, __.Constant<object>(\"none\")).Option(xx1, __.Constant<object>(\"one\")).Option(xx2, __.Constant<object>(\"many\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Out(\"created\").Count()).Option(xx0, gremlingo.T__.Constant(\"none\")).Option(xx1, gremlingo.T__.Constant(\"one\")).Option(xx2, gremlingo.T__.Constant(\"many\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count()).option(xx0, __.constant(\"none\")).option(xx1, __.constant(\"one\")).option(xx2, __.constant(\"many\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count()).option(xx0, __.constant(\"none\")).option(xx1, __.constant(\"one\")).option(xx2, __.constant(\"many\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.out(\"created\").count()).option(xx0, __.constant(\"none\")).option(xx1, __.constant(\"one\")).option(xx2, __.constant(\"many\"))",
+ "python": "g.V().has_label('person').choose(__.out('created').count()).option(xx0, __.constant('none')).option(xx1, __.constant('one')).option(xx2, __.constant('many'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseXlocalXoutXknowsX_countX__optionX0__constantXnoFriendsXX__optionXnone__constantXhasFriendsXXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(__.local(__.out(\"knows\").count())).option(xx0, __.constant(\"noFriends\")).option(Pick.none, __.constant(\"hasFriends\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.local(__.out(\"knows\").count())).option(xx0, __.constant(\"noFriends\")).option(Pick.none, __.constant(\"hasFriends\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.local(__.out(string1).count())).option(xx0, __.constant(string2)).option(Pick.none, __.constant(string3))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Local<object>(__.Out(\"knows\").Count())).Option(xx0, __.Constant<object>(\"noFriends\")).Option(Pick.None, __.Constant<object>(\"hasFriends\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Local(gremlingo.T__.Out(\"knows\").Count())).Option(xx0, gremlingo.T__.Constant(\"noFriends\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"hasFriends\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.local(__.out(\"knows\").count())).option(xx0, __.constant(\"noFriends\")).option(Pick.none, __.constant(\"hasFriends\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.local(__.out(\"knows\").count())).option(xx0, __.constant(\"noFriends\")).option(Pick.none, __.constant(\"hasFriends\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.local(__.out(\"knows\").count())).option(xx0, __.constant(\"noFriends\")).option(Pick.none, __.constant(\"hasFriends\"))",
+ "python": "g.V().has_label('person').choose(__.local(__.out('knows').count())).option(xx0, __.constant('noFriends')).option(Pick.none, __.constant('hasFriends'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXoutE_countX_optionX0__constantXnoneXX_optionXnone__constantXsomeXX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.outE().count()).option(xx0, __.constant(\"none\")).option(Pick.none, __.constant(\"some\"))",
+ "language": "g.V().choose(__.outE().count()).option(xx0, __.constant(\"none\")).option(Pick.none, __.constant(\"some\"))",
+ "anonymized": "g.V().choose(__.outE().count()).option(xx0, __.constant(string0)).option(Pick.none, __.constant(string1))",
+ "dotnet": "g.V().Choose<object>(__.OutE().Count()).Option(xx0, __.Constant<object>(\"none\")).Option(Pick.None, __.Constant<object>(\"some\"))",
+ "go": "g.V().Choose(gremlingo.T__.OutE().Count()).Option(xx0, gremlingo.T__.Constant(\"none\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"some\"))",
+ "groovy": "g.V().choose(__.outE().count()).option(xx0, __.constant(\"none\")).option(Pick.none, __.constant(\"some\"))",
+ "java": "g.V().choose(__.outE().count()).option(xx0, __.constant(\"none\")).option(Pick.none, __.constant(\"some\"))",
+ "javascript": "g.V().choose(__.outE().count()).option(xx0, __.constant(\"none\")).option(Pick.none, __.constant(\"some\"))",
+ "python": "g.V().choose(__.out_e().count()).option(xx0, __.constant('none')).option(Pick.none, __.constant('some'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXlabelX_optionXperson__chooseXageX_optionXP_lt_30__constantXyoungXX_optionXP_gte_30__constantXoldXXX_optionXsoftware__constantXprogramXX_optionXnone__constantXunknownXX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.label()).option(\"person\", __.choose(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gte(30), __.constant(\"old\"))).option(\"software\", __.constant(\"program\")).option(Pick.none, __.constant(\"unknown\"))",
+ "language": "g.V().choose(__.label()).option(\"person\", __.choose(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gte(30), __.constant(\"old\"))).option(\"software\", __.constant(\"program\")).option(Pick.none, __.constant(\"unknown\"))",
+ "anonymized": "g.V().choose(__.label()).option(string0, __.choose(__.values(string1)).option(P.lt(number0), __.constant(string2)).option(P.gte(number0), __.constant(string3))).option(string4, __.constant(string5)).option(Pick.none, __.constant(string6))",
+ "dotnet": "g.V().Choose<object>(__.Label()).Option(\"person\", __.Choose<object>(__.Values<object>(\"age\")).Option(P.Lt(30), __.Constant<object>(\"young\")).Option(P.Gte(30), __.Constant<object>(\"old\"))).Option(\"software\", __.Constant<object>(\"program\")).Option(Pick.None, __.Constant<object>(\"unknown\"))",
+ "go": "g.V().Choose(gremlingo.T__.Label()).Option(\"person\", gremlingo.T__.Choose(gremlingo.T__.Values(\"age\")).Option(gremlingo.P.Lt(30), gremlingo.T__.Constant(\"young\")).Option(gremlingo.P.Gte(30), gremlingo.T__.Constant(\"old\"))).Option(\"software\", gremlingo.T__.Constant(\"program\")).Option(gremlingo.Pick.None, gremlingo.T__.Constant(\"unknown\"))",
+ "groovy": "g.V().choose(__.label()).option(\"person\", __.choose(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gte(30), __.constant(\"old\"))).option(\"software\", __.constant(\"program\")).option(Pick.none, __.constant(\"unknown\"))",
+ "java": "g.V().choose(__.label()).option(\"person\", __.choose(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gte(30), __.constant(\"old\"))).option(\"software\", __.constant(\"program\")).option(Pick.none, __.constant(\"unknown\"))",
+ "javascript": "g.V().choose(__.label()).option(\"person\", __.choose(__.values(\"age\")).option(P.lt(30), __.constant(\"young\")).option(P.gte(30), __.constant(\"old\"))).option(\"software\", __.constant(\"program\")).option(Pick.none, __.constant(\"unknown\"))",
+ "python": "g.V().choose(__.label()).option('person', __.choose(__.values('age')).option(P.lt(30), __.constant('young')).option(P.gte(30), __.constant('old'))).option('software', __.constant('program')).option(Pick.none, __.constant('unknown'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXhasXname_vadasX__valuesXnameXX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.has(\"name\", \"vadas\"),__.values(\"name\"))",
+ "language": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"))",
+ "anonymized": "g.V().choose(__.has(string0, string1), __.values(string0))",
+ "dotnet": "g.V().Choose<object>(__.Has(\"name\", \"vadas\"), __.Values<object>(\"name\"))",
+ "go": "g.V().Choose(gremlingo.T__.Has(\"name\", \"vadas\"), gremlingo.T__.Values(\"name\"))",
+ "groovy": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"))",
+ "java": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"))",
+ "javascript": "g.V().choose(__.has(\"name\", \"vadas\"), __.values(\"name\"))",
+ "python": "g.V().choose(__.has('name', 'vadas'), __.values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_age_chooseXP_eqX29X_constantXmatchedX_constantXotherXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29),__.constant(\"matched\"),__.constant(\"other\"))",
+ "language": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"), __.constant(\"other\"))",
+ "anonymized": "g.V().hasLabel(string0).values(string1).choose(P.eq(number0), __.constant(string2), __.constant(string3))",
+ "dotnet": "g.V().HasLabel(\"person\").Values<object>(\"age\").Choose<object>(P.Eq(29), __.Constant<object>(\"matched\"), __.Constant<object>(\"other\"))",
+ "go": "g.V().HasLabel(\"person\").Values(\"age\").Choose(gremlingo.P.Eq(29), gremlingo.T__.Constant(\"matched\"), gremlingo.T__.Constant(\"other\"))",
+ "groovy": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"), __.constant(\"other\"))",
+ "java": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"), __.constant(\"other\"))",
+ "javascript": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"), __.constant(\"other\"))",
+ "python": "g.V().has_label('person').values('age').choose(P.eq(29), __.constant('matched'), __.constant('other'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_age_chooseXP_eqX29X_constantXmatchedX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29),__.constant(\"matched\"))",
+ "language": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"))",
+ "anonymized": "g.V().hasLabel(string0).values(string1).choose(P.eq(number0), __.constant(string2))",
+ "dotnet": "g.V().HasLabel(\"person\").Values<object>(\"age\").Choose<object>(P.Eq(29), __.Constant<object>(\"matched\"))",
+ "go": "g.V().HasLabel(\"person\").Values(\"age\").Choose(gremlingo.P.Eq(29), gremlingo.T__.Constant(\"matched\"))",
+ "groovy": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"))",
+ "java": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"))",
+ "javascript": "g.V().hasLabel(\"person\").values(\"age\").choose(P.eq(29), __.constant(\"matched\"))",
+ "python": "g.V().has_label('person').values('age').choose(P.eq(29), __.constant('matched'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseX_valuesXnameX_option1X_isXmarkoX_valuesXageXX_option2Xnone_valuesXnameXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(values(\"name\")).option(is(\"marko\"), values(\"age\")).option(Pick.none, values(\"name\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(__.is(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1)).option(__.is(string2), __.values(string3)).option(Pick.none, __.values(string1))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"name\")).Option(__.Is(\"marko\"), __.Values<object>(\"age\")).Option(Pick.None, __.Values<object>(\"name\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"name\")).Option(gremlingo.T__.Is(\"marko\"), gremlingo.T__.Values(\"age\")).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(__.is(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(__.is(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(__.is(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "python": "g.V().has_label('person').choose(__.values('name')).option(__.is_('marko'), __.values('age')).option(Pick.none, __.values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_chooseX_valuesXnameX_option1X_PeqXmarkoX_valuesXageXX_option2Xnone_valuesXnameXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").choose(values(\"name\")).option(P.eq(\"marko\"), values(\"age\")).option(Pick.none, values(\"name\"))",
+ "language": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(P.eq(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "anonymized": "g.V().hasLabel(string0).choose(__.values(string1)).option(P.eq(string2), __.values(string3)).option(Pick.none, __.values(string1))",
+ "dotnet": "g.V().HasLabel(\"person\").Choose<object>(__.Values<object>(\"name\")).Option(P.Eq(\"marko\"), __.Values<object>(\"age\")).Option(Pick.None, __.Values<object>(\"name\"))",
+ "go": "g.V().HasLabel(\"person\").Choose(gremlingo.T__.Values(\"name\")).Option(gremlingo.P.Eq(\"marko\"), gremlingo.T__.Values(\"age\")).Option(gremlingo.Pick.None, gremlingo.T__.Values(\"name\"))",
+ "groovy": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(P.eq(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "java": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(P.eq(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "javascript": "g.V().hasLabel(\"person\").choose(__.values(\"name\")).option(P.eq(\"marko\"), __.values(\"age\")).option(Pick.none, __.values(\"name\"))",
+ "python": "g.V().has_label('person').choose(__.values('name')).option(P.eq('marko'), __.values('age')).option(Pick.none, __.values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXpropertiesXlocationX_order_byXvalueX_limitX2XX_value",
+ "traversals": [
+ {
+ "original": "g.V().local(__.properties(\"location\").order().by(T.value, Order.asc).range(0, 2)).value()",
+ "language": "g.V().local(__.properties(\"location\").order().by(T.value, Order.asc).range(0, 2)).value()",
+ "anonymized": "g.V().local(__.properties(string0).order().by(T.value, Order.asc).range(number0, number1)).value()",
+ "dotnet": "g.V().Local<object>(__.Properties<object>(\"location\").Order().By(T.Value, Order.Asc).Range<object>(0, 2)).Value<object>()",
+ "go": "g.V().Local(gremlingo.T__.Properties(\"location\").Order().By(gremlingo.T.Value, gremlingo.Order.Asc).Range(0, 2)).Value()",
+ "groovy": "g.V().local(__.properties(\"location\").order().by(T.value, Order.asc).range(0, 2)).value()",
+ "java": "g.V().local(__.properties(\"location\").order().by(T.value, Order.asc).range(0, 2)).value()",
+ "javascript": "g.V().local(__.properties(\"location\").order().by(T.value, Order.asc).range(0, 2)).value()",
+ "python": "g.V().local(__.properties('location').order().by(T.value, Order.asc).range_(0, 2)).value()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXlabel_personX_asXaX_localXoutXcreatedX_asXbXX_selectXa_bX_byXnameX_byXidX",
+ "traversals": [
+ {
+ "original": "g.V().has(T.label, \"person\").as(\"a\").local(__.out(\"created\").as(\"b\")).select(\"a\", \"b\").by(\"name\").by(T.id)",
+ "language": "g.V().has(T.label, \"person\").as(\"a\").local(__.out(\"created\").as(\"b\")).select(\"a\", \"b\").by(\"name\").by(T.id)",
+ "anonymized": "g.V().has(T.label, string0).as(string1).local(__.out(string2).as(string3)).select(string1, string3).by(string4).by(T.id)",
+ "dotnet": "g.V().Has(T.Label, \"person\").As(\"a\").Local<object>(__.Out(\"created\").As(\"b\")).Select<object>(\"a\", \"b\").By(\"name\").By(T.Id)",
+ "go": "g.V().Has(gremlingo.T.Label, \"person\").As(\"a\").Local(gremlingo.T__.Out(\"created\").As(\"b\")).Select(\"a\", \"b\").By(\"name\").By(gremlingo.T.Id)",
+ "groovy": "g.V().has(T.label, \"person\").as(\"a\").local(__.out(\"created\").as(\"b\")).select(\"a\", \"b\").by(\"name\").by(T.id)",
+ "java": "g.V().has(T.label, \"person\").as(\"a\").local(__.out(\"created\").as(\"b\")).select(\"a\", \"b\").by(\"name\").by(T.id)",
+ "javascript": "g.V().has(T.label, \"person\").as(\"a\").local(__.out(\"created\").as(\"b\")).select(\"a\", \"b\").by(\"name\").by(T.id)",
+ "python": "g.V().has(T.label, 'person').as_('a').local(__.out('created').as_('b')).select('a', 'b').by('name').by(T.id_)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXoutE_countX",
+ "traversals": [
+ {
+ "original": "g.V().local(__.outE().count())",
+ "language": "g.V().local(__.outE().count())",
+ "anonymized": "g.V().local(__.outE().count())",
+ "dotnet": "g.V().Local<object>(__.OutE().Count())",
+ "go": "g.V().Local(gremlingo.T__.OutE().Count())",
+ "groovy": "g.V().local(__.outE().count())",
+ "java": "g.V().local(__.outE().count())",
+ "javascript": "g.V().local(__.outE().count())",
+ "python": "g.V().local(__.out_e().count())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_localXoutEXknowsX_limitX1XX_inV_name",
+ "traversals": [
+ {
+ "original": "g.V(vid1).local(__.outE(\"knows\").limit(1)).inV().values(\"name\")",
+ "language": "g.V(vid1).local(__.outE(\"knows\").limit(1)).inV().values(\"name\")",
+ "anonymized": "g.V(vid1).local(__.outE(string0).limit(number0)).inV().values(string1)",
+ "dotnet": "g.V(vid1).Local<object>(__.OutE(\"knows\").Limit<object>(1)).InV().Values<object>(\"name\")",
+ "go": "g.V(vid1).Local(gremlingo.T__.OutE(\"knows\").Limit(1)).InV().Values(\"name\")",
+ "groovy": "g.V(vid1).local(__.outE(\"knows\").limit(1)).inV().values(\"name\")",
+ "java": "g.V(vid1).local(__.outE(\"knows\").limit(1)).inV().values(\"name\")",
+ "javascript": "g.V(vid1).local(__.outE(\"knows\").limit(1)).inV().values(\"name\")",
+ "python": "g.V(vid1).local(__.out_e('knows').limit(1)).in_v().values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXbothEXcreatedX_limitX1XX_otherV_name",
+ "traversals": [
+ {
+ "original": "g.V().local(__.bothE(\"created\").limit(1)).otherV().values(\"name\")",
+ "language": "g.V().local(__.bothE(\"created\").limit(1)).otherV().values(\"name\")",
+ "anonymized": "g.V().local(__.bothE(string0).limit(number0)).otherV().values(string1)",
+ "dotnet": "g.V().Local<object>(__.BothE(\"created\").Limit<object>(1)).OtherV().Values<object>(\"name\")",
+ "go": "g.V().Local(gremlingo.T__.BothE(\"created\").Limit(1)).OtherV().Values(\"name\")",
+ "groovy": "g.V().local(__.bothE(\"created\").limit(1)).otherV().values(\"name\")",
+ "java": "g.V().local(__.bothE(\"created\").limit(1)).otherV().values(\"name\")",
+ "javascript": "g.V().local(__.bothE(\"created\").limit(1)).otherV().values(\"name\")",
+ "python": "g.V().local(__.both_e('created').limit(1)).other_v().values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX4X_localXbothEX1_createdX_limitX1XX",
+ "traversals": [
+ {
+ "original": "g.V(vid4).local(__.bothE(\"created\").limit(1))",
+ "language": "g.V(vid4).local(__.bothE(\"created\").limit(1))",
+ "anonymized": "g.V(vid4).local(__.bothE(string0).limit(number0))",
+ "dotnet": "g.V(vid4).Local<object>(__.BothE(\"created\").Limit<object>(1))",
+ "go": "g.V(vid4).Local(gremlingo.T__.BothE(\"created\").Limit(1))",
+ "groovy": "g.V(vid4).local(__.bothE(\"created\").limit(1))",
+ "java": "g.V(vid4).local(__.bothE(\"created\").limit(1))",
+ "javascript": "g.V(vid4).local(__.bothE(\"created\").limit(1))",
+ "python": "g.V(vid4).local(__.both_e('created').limit(1))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX4X_localXbothEXknows_createdX_limitX1XX",
+ "traversals": [
+ {
+ "original": "g.V(vid4).local(__.bothE(\"knows\", \"created\").limit(1))",
+ "language": "g.V(vid4).local(__.bothE(\"knows\", \"created\").limit(1))",
+ "anonymized": "g.V(vid4).local(__.bothE(string0, string1).limit(number0))",
+ "dotnet": "g.V(vid4).Local<object>(__.BothE(\"knows\", \"created\").Limit<object>(1))",
+ "go": "g.V(vid4).Local(gremlingo.T__.BothE(\"knows\", \"created\").Limit(1))",
+ "groovy": "g.V(vid4).local(__.bothE(\"knows\", \"created\").limit(1))",
+ "java": "g.V(vid4).local(__.bothE(\"knows\", \"created\").limit(1))",
+ "javascript": "g.V(vid4).local(__.bothE(\"knows\", \"created\").limit(1))",
+ "python": "g.V(vid4).local(__.both_e('knows', 'created').limit(1))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX4X_localXbothE_limitX1XX_otherV_name",
+ "traversals": [
+ {
+ "original": "g.V(vid4).local(__.bothE().limit(1)).otherV().values(\"name\")",
+ "language": "g.V(vid4).local(__.bothE().limit(1)).otherV().values(\"name\")",
+ "anonymized": "g.V(vid4).local(__.bothE().limit(number0)).otherV().values(string0)",
+ "dotnet": "g.V(vid4).Local<object>(__.BothE().Limit<object>(1)).OtherV().Values<object>(\"name\")",
+ "go": "g.V(vid4).Local(gremlingo.T__.BothE().Limit(1)).OtherV().Values(\"name\")",
+ "groovy": "g.V(vid4).local(__.bothE().limit(1)).otherV().values(\"name\")",
+ "java": "g.V(vid4).local(__.bothE().limit(1)).otherV().values(\"name\")",
+ "javascript": "g.V(vid4).local(__.bothE().limit(1)).otherV().values(\"name\")",
+ "python": "g.V(vid4).local(__.both_e().limit(1)).other_v().values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX4X_localXbothE_limitX2XX_otherV_name",
+ "traversals": [
+ {
+ "original": "g.V(vid4).local(__.bothE().limit(2)).otherV().values(\"name\")",
+ "language": "g.V(vid4).local(__.bothE().limit(2)).otherV().values(\"name\")",
+ "anonymized": "g.V(vid4).local(__.bothE().limit(number0)).otherV().values(string0)",
+ "dotnet": "g.V(vid4).Local<object>(__.BothE().Limit<object>(2)).OtherV().Values<object>(\"name\")",
+ "go": "g.V(vid4).Local(gremlingo.T__.BothE().Limit(2)).OtherV().Values(\"name\")",
+ "groovy": "g.V(vid4).local(__.bothE().limit(2)).otherV().values(\"name\")",
+ "java": "g.V(vid4).local(__.bothE().limit(2)).otherV().values(\"name\")",
+ "javascript": "g.V(vid4).local(__.bothE().limit(2)).otherV().values(\"name\")",
+ "python": "g.V(vid4).local(__.both_e().limit(2)).other_v().values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXinEXknowsX_limitX2XX_outV_name",
+ "traversals": [
+ {
+ "original": "g.V().local(__.inE(\"knows\").limit(2)).outV().values(\"name\")",
+ "language": "g.V().local(__.inE(\"knows\").limit(2)).outV().values(\"name\")",
+ "anonymized": "g.V().local(__.inE(string0).limit(number0)).outV().values(string1)",
+ "dotnet": "g.V().Local<object>(__.InE(\"knows\").Limit<object>(2)).OutV().Values<object>(\"name\")",
+ "go": "g.V().Local(gremlingo.T__.InE(\"knows\").Limit(2)).OutV().Values(\"name\")",
+ "groovy": "g.V().local(__.inE(\"knows\").limit(2)).outV().values(\"name\")",
+ "java": "g.V().local(__.inE(\"knows\").limit(2)).outV().values(\"name\")",
+ "javascript": "g.V().local(__.inE(\"knows\").limit(2)).outV().values(\"name\")",
+ "python": "g.V().local(__.in_e('knows').limit(2)).out_v().values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXmatchXproject__created_person__person_name_nameX_selectXname_projectX_by_byXnameX",
+ "traversals": [
+ {
+ "original": "g.V().local(__.match(__.as(\"project\").in(\"created\").as(\"person\"),__.as(\"person\").values(\"name\").as(\"name\"))).select(\"name\", \"project\").by().by(\"name\")",
+ "language": "g.V().local(__.match(__.as(\"project\").in(\"created\").as(\"person\"), __.as(\"person\").values(\"name\").as(\"name\"))).select(\"name\", \"project\").by().by(\"name\")",
+ "anonymized": "g.V().local(__.match(__.as(string0).in(string1).as(string2), __.as(string2).values(string3).as(string3))).select(string3, string0).by().by(string3)",
+ "dotnet": "g.V().Local<object>(__.Match<object>(__.As(\"project\").In(\"created\").As(\"person\"), __.As(\"person\").Values<object>(\"name\").As(\"name\"))).Select<object>(\"name\", \"project\").By().By(\"name\")",
+ "go": "g.V().Local(gremlingo.T__.Match(gremlingo.T__.As(\"project\").In(\"created\").As(\"person\"), gremlingo.T__.As(\"person\").Values(\"name\").As(\"name\"))).Select(\"name\", \"project\").By().By(\"name\")",
+ "groovy": "g.V().local(__.match(__.as(\"project\").in(\"created\").as(\"person\"), __.as(\"person\").values(\"name\").as(\"name\"))).select(\"name\", \"project\").by().by(\"name\")",
+ "java": "g.V().local(__.match(__.as(\"project\").in(\"created\").as(\"person\"), __.as(\"person\").values(\"name\").as(\"name\"))).select(\"name\", \"project\").by().by(\"name\")",
+ "javascript": "g.V().local(__.match(__.as(\"project\").in_(\"created\").as(\"person\"), __.as(\"person\").values(\"name\").as(\"name\"))).select(\"name\", \"project\").by().by(\"name\")",
+ "python": "g.V().local(__.match(__.as_('project').in_('created').as_('person'), __.as_('person').values('name').as_('name'))).select('name', 'project').by().by('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_in_barrier_localXcountX",
+ "traversals": [
+ {
+ "original": "g.V().in().barrier().local(__.count())",
+ "language": "g.V().in().barrier().local(__.count())",
+ "anonymized": "g.V().in().barrier().local(__.count())",
+ "dotnet": "g.V().In().Barrier().Local<object>(__.Count())",
+ "go": "g.V().In().Barrier().Local(gremlingo.T__.Count())",
+ "groovy": "g.V().in().barrier().local(__.count())",
+ "java": "g.V().in().barrier().local(__.count())",
+ "javascript": "g.V().in_().barrier().local(__.count())",
+ "python": "g.V().in_().barrier().local(__.count())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXout_in_simplePathX_path",
+ "traversals": [
+ {
+ "original": "g.V().local(__.out().in().simplePath()).path()",
+ "language": "g.V().local(__.out().in().simplePath()).path()",
+ "anonymized": "g.V().local(__.out().in().simplePath()).path()",
+ "dotnet": "g.V().Local<object>(__.Out().In().SimplePath()).Path()",
+ "go": "g.V().Local(gremlingo.T__.Out().In().SimplePath()).Path()",
+ "groovy": "g.V().local(__.out().in().simplePath()).path()",
+ "java": "g.V().local(__.out().in().simplePath()).path()",
+ "javascript": "g.V().local(__.out().in_().simplePath()).path()",
+ "python": "g.V().local(__.out().in_().simple_path()).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_withSackX0LX_V_in_barrier_localXsackXsumX_byXageXX_sack",
+ "traversals": [
+ {
+ "original": "g.withSack(0L).V().in().barrier().local(__.sack(sum).by(\"age\")).sack()",
+ "language": "g.withSack(0l).V().in().barrier().local(__.sack(Operator.sum).by(\"age\")).sack()",
+ "anonymized": "g.withSack(long0).V().in().barrier().local(__.sack(Operator.sum).by(string0)).sack()",
+ "dotnet": "g.WithSack(0l).V().In().Barrier().Local<object>(__.Sack(Operator.Sum).By(\"age\")).Sack<object>()",
+ "go": "g.WithSack(int64(0)).V().In().Barrier().Local(gremlingo.T__.Sack(gremlingo.Operator.Sum).By(\"age\")).Sack()",
+ "groovy": "g.withSack(0l).V().in().barrier().local(__.sack(Operator.sum).by(\"age\")).sack()",
+ "java": "g.withSack(0l).V().in().barrier().local(__.sack(Operator.sum).by(\"age\")).sack()",
+ "javascript": "g.withSack(0).V().in_().barrier().local(__.sack(Operator.sum).by(\"age\")).sack()",
+ "python": "g.with_sack(long(0)).V().in_().barrier().local(__.sack(Operator.sum_).by('age')).sack()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXout_localXcountXX",
+ "traversals": [
+ {
+ "original": "g.V().local(__.out().local(__.count()))",
+ "language": "g.V().local(__.out().local(__.count()))",
+ "anonymized": "g.V().local(__.out().local(__.count()))",
+ "dotnet": "g.V().Local<object>(__.Out().Local<object>(__.Count()))",
+ "go": "g.V().Local(gremlingo.T__.Out().Local(gremlingo.T__.Count()))",
+ "groovy": "g.V().local(__.out().local(__.count()))",
+ "java": "g.V().local(__.out().local(__.count()))",
+ "javascript": "g.V().local(__.out().local(__.count()))",
+ "python": "g.V().local(__.out().local(__.count()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_unionXoutE_count_localXinE_countXX",
+ "traversals": [
+ {
+ "original": "g.V().union(__.outE().count(), __.local(inE().count()))",
+ "language": "g.V().union(__.outE().count(), __.local(__.inE().count()))",
+ "anonymized": "g.V().union(__.outE().count(), __.local(__.inE().count()))",
+ "dotnet": "g.V().Union<object>(__.OutE().Count(), __.Local<object>(__.InE().Count()))",
+ "go": "g.V().Union(gremlingo.T__.OutE().Count(), gremlingo.T__.Local(gremlingo.T__.InE().Count()))",
+ "groovy": "g.V().union(__.outE().count(), __.local(__.inE().count()))",
+ "java": "g.V().union(__.outE().count(), __.local(__.inE().count()))",
+ "javascript": "g.V().union(__.outE().count(), __.local(__.inE().count()))",
+ "python": "g.V().union(__.out_e().count(), __.local(__.in_e().count()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX2X_optionalXoutXknowsXX",
+ "traversals": [
+ {
+ "original": "g.V(vid2).optional(__.out(\"knows\"))",
+ "language": "g.V(vid2).optional(__.out(\"knows\"))",
+ "anonymized": "g.V(vid2).optional(__.out(string0))",
+ "dotnet": "g.V(vid2).Optional<object>(__.Out(\"knows\"))",
+ "go": "g.V(vid2).Optional(gremlingo.T__.Out(\"knows\"))",
+ "groovy": "g.V(vid2).optional(__.out(\"knows\"))",
+ "java": "g.V(vid2).optional(__.out(\"knows\"))",
+ "javascript": "g.V(vid2).optional(__.out(\"knows\"))",
+ "python": "g.V(vid2).optional(__.out('knows'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX2X_optionalXinXknowsXX",
+ "traversals": [
+ {
+ "original": "g.V(vid2).optional(__.in(\"knows\"))",
+ "language": "g.V(vid2).optional(__.in(\"knows\"))",
+ "anonymized": "g.V(vid2).optional(__.in(string0))",
+ "dotnet": "g.V(vid2).Optional<object>(__.In(\"knows\"))",
+ "go": "g.V(vid2).Optional(gremlingo.T__.In(\"knows\"))",
+ "groovy": "g.V(vid2).optional(__.in(\"knows\"))",
+ "java": "g.V(vid2).optional(__.in(\"knows\"))",
+ "javascript": "g.V(vid2).optional(__.in_(\"knows\"))",
+ "python": "g.V(vid2).optional(__.in_('knows'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_optionalXoutXknowsX_optionalXoutXcreatedXXX_path",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").optional(__.out(\"knows\").optional(__.out(\"created\"))).path()",
+ "language": "g.V().hasLabel(\"person\").optional(__.out(\"knows\").optional(__.out(\"created\"))).path()",
+ "anonymized": "g.V().hasLabel(string0).optional(__.out(string1).optional(__.out(string2))).path()",
+ "dotnet": "g.V().HasLabel(\"person\").Optional<object>(__.Out(\"knows\").Optional<object>(__.Out(\"created\"))).Path()",
+ "go": "g.V().HasLabel(\"person\").Optional(gremlingo.T__.Out(\"knows\").Optional(gremlingo.T__.Out(\"created\"))).Path()",
+ "groovy": "g.V().hasLabel(\"person\").optional(__.out(\"knows\").optional(__.out(\"created\"))).path()",
+ "java": "g.V().hasLabel(\"person\").optional(__.out(\"knows\").optional(__.out(\"created\"))).path()",
+ "javascript": "g.V().hasLabel(\"person\").optional(__.out(\"knows\").optional(__.out(\"created\"))).path()",
+ "python": "g.V().has_label('person').optional(__.out('knows').optional(__.out('created'))).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_optionalXout_optionalXoutXX_path",
+ "traversals": [
+ {
+ "original": "g.V().optional(__.out().optional(__.out())).path()",
+ "language": "g.V().optional(__.out().optional(__.out())).path()",
+ "anonymized": "g.V().optional(__.out().optional(__.out())).path()",
+ "dotnet": "g.V().Optional<object>(__.Out().Optional<object>(__.Out())).Path()",
+ "go": "g.V().Optional(gremlingo.T__.Out().Optional(gremlingo.T__.Out())).Path()",
+ "groovy": "g.V().optional(__.out().optional(__.out())).path()",
+ "java": "g.V().optional(__.out().optional(__.out())).path()",
+ "javascript": "g.V().optional(__.out().optional(__.out())).path()",
+ "python": "g.V().optional(__.out().optional(__.out())).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_optionalXaddVXdogXX_label",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").property(\"age\", 29).as(\"marko\").addV(\"person\").property(\"name\", \"vadas\").property(\"age\", 27).as(\"vadas\").addV(\"software\").property(\"name\", \"lop\").property(\"lang\", \"java\").as(\"lop\").addV(\"person\").property(\"name\",\"josh\").property(\"age\", 32).as(\"josh\").addV(\"software\").property(\"name\", \"ripple\").property(\"lang\", \"java\").as(\"ripple\").addV(\"person\").property(\"name\ [...]
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").property(\"age\", 29).as(\"marko\").addV(\"person\").property(\"name\", \"vadas\").property(\"age\", 27).as(\"vadas\").addV(\"software\").property(\"name\", \"lop\").property(\"lang\", \"java\").as(\"lop\").addV(\"person\").property(\"name\", \"josh\").property(\"age\", 32).as(\"josh\").addV(\"software\").property(\"name\", \"ripple\").property(\"lang\", \"java\").as(\"ripple\").addV(\"person\").property(\"name [...]
+ "anonymized": "g.addV(string0).property(string1, string2).property(string3, number0).as(string2).addV(string0).property(string1, string4).property(string3, number1).as(string4).addV(string5).property(string1, string6).property(string7, string8).as(string6).addV(string0).property(string1, string9).property(string3, number2).as(string9).addV(string5).property(string1, string10).property(string7, string8).as(string10).addV(string0).property(string1, string11).property(string [...]
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").Property(\"age\", 29).As(\"marko\").AddV((string) \"person\").Property(\"name\", \"vadas\").Property(\"age\", 27).As(\"vadas\").AddV((string) \"software\").Property(\"name\", \"lop\").Property(\"lang\", \"java\").As(\"lop\").AddV((string) \"person\").Property(\"name\", \"josh\").Property(\"age\", 32).As(\"josh\").AddV((string) \"software\").Property(\"name\", \"ripple\").Property(\"lang\", \"java\").As(\ [...]
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").Property(\"age\", 29).As(\"marko\").AddV(\"person\").Property(\"name\", \"vadas\").Property(\"age\", 27).As(\"vadas\").AddV(\"software\").Property(\"name\", \"lop\").Property(\"lang\", \"java\").As(\"lop\").AddV(\"person\").Property(\"name\", \"josh\").Property(\"age\", 32).As(\"josh\").AddV(\"software\").Property(\"name\", \"ripple\").Property(\"lang\", \"java\").As(\"ripple\").AddV(\"person\").Property(\"name\", \" [...]
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").property(\"age\", 29).as(\"marko\").addV(\"person\").property(\"name\", \"vadas\").property(\"age\", 27).as(\"vadas\").addV(\"software\").property(\"name\", \"lop\").property(\"lang\", \"java\").as(\"lop\").addV(\"person\").property(\"name\", \"josh\").property(\"age\", 32).as(\"josh\").addV(\"software\").property(\"name\", \"ripple\").property(\"lang\", \"java\").as(\"ripple\").addV(\"person\").property(\"name\" [...]
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").property(\"age\", 29).as(\"marko\").addV(\"person\").property(\"name\", \"vadas\").property(\"age\", 27).as(\"vadas\").addV(\"software\").property(\"name\", \"lop\").property(\"lang\", \"java\").as(\"lop\").addV(\"person\").property(\"name\", \"josh\").property(\"age\", 32).as(\"josh\").addV(\"software\").property(\"name\", \"ripple\").property(\"lang\", \"java\").as(\"ripple\").addV(\"person\").property(\"name\", [...]
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").property(\"age\", 29).as(\"marko\").addV(\"person\").property(\"name\", \"vadas\").property(\"age\", 27).as(\"vadas\").addV(\"software\").property(\"name\", \"lop\").property(\"lang\", \"java\").as(\"lop\").addV(\"person\").property(\"name\", \"josh\").property(\"age\", 32).as(\"josh\").addV(\"software\").property(\"name\", \"ripple\").property(\"lang\", \"java\").as(\"ripple\").addV(\"person\").property(\"na [...]
+ "python": "g.add_v('person').property('name', 'marko').property('age', 29).as_('marko').add_v('person').property('name', 'vadas').property('age', 27).as_('vadas').add_v('software').property('name', 'lop').property('lang', 'java').as_('lop').add_v('person').property('name', 'josh').property('age', 32).as_('josh').add_v('software').property('name', 'ripple').property('lang', 'java').as_('ripple').add_v('person').property('name', 'peter').property('age', 35).as_('peter').add [...]
+ },
+ {
+ "original": "g.V(vid1).optional(__.addV(\"dog\")).label()",
+ "language": "g.V(vid1).optional(__.addV(\"dog\")).label()",
+ "anonymized": "g.V(vid1).optional(__.addV(string0)).label()",
+ "dotnet": "g.V(vid1).Optional<object>(__.AddV((string) \"dog\")).Label()",
+ "go": "g.V(vid1).Optional(gremlingo.T__.AddV(\"dog\")).Label()",
+ "groovy": "g.V(vid1).optional(__.addV(\"dog\")).label()",
+ "java": "g.V(vid1).optional(__.addV(\"dog\")).label()",
+ "javascript": "g.V(vid1).optional(__.addV(\"dog\")).label()",
+ "python": "g.V(vid1).optional(__.add_v('dog')).label()"
+ },
+ {
+ "original": "g.V()",
+ "language": "g.V()",
+ "anonymized": "g.V()",
+ "dotnet": "g.V()",
+ "go": "g.V()",
+ "groovy": "g.V()",
+ "java": "g.V()",
+ "javascript": "g.V()",
+ "python": "g.V()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXoutX_timesX2X_emit_path",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.out()).times(2).emit().path()",
+ "language": "g.V().repeat(__.out()).times(2).emit().path()",
+ "anonymized": "g.V().repeat(__.out()).times(number0).emit().path()",
+ "dotnet": "g.V().Repeat(__.Out()).Times(2).Emit().Path()",
+ "go": "g.V().Repeat(gremlingo.T__.Out()).Times(2).Emit().Path()",
+ "groovy": "g.V().repeat(__.out()).times(2).emit().path()",
+ "java": "g.V().repeat(__.out()).times(2).emit().path()",
+ "javascript": "g.V().repeat(__.out()).times(2).emit().path()",
+ "python": "g.V().repeat(__.out()).times(2).emit().path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXoutX_timesX2X_repeatXinX_timesX2X_name",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.out()).times(2).repeat(__.in()).times(2).values(\"name\")",
+ "language": "g.V().repeat(__.out()).times(2).repeat(__.in()).times(2).values(\"name\")",
+ "anonymized": "g.V().repeat(__.out()).times(number0).repeat(__.in()).times(number0).values(string0)",
+ "dotnet": "g.V().Repeat(__.Out()).Times(2).Repeat(__.In()).Times(2).Values<object>(\"name\")",
+ "go": "g.V().Repeat(gremlingo.T__.Out()).Times(2).Repeat(gremlingo.T__.In()).Times(2).Values(\"name\")",
+ "groovy": "g.V().repeat(__.out()).times(2).repeat(__.in()).times(2).values(\"name\")",
+ "java": "g.V().repeat(__.out()).times(2).repeat(__.in()).times(2).values(\"name\")",
+ "javascript": "g.V().repeat(__.out()).times(2).repeat(__.in_()).times(2).values(\"name\")",
+ "python": "g.V().repeat(__.out()).times(2).repeat(__.in_()).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXoutE_inVX_timesX2X_path_by_name_by_label",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.outE().inV()).times(2).path().by(\"name\").by(T.label)",
+ "language": "g.V().repeat(__.outE().inV()).times(2).path().by(\"name\").by(T.label)",
+ "anonymized": "g.V().repeat(__.outE().inV()).times(number0).path().by(string0).by(T.label)",
+ "dotnet": "g.V().Repeat(__.OutE().InV()).Times(2).Path().By(\"name\").By(T.Label)",
+ "go": "g.V().Repeat(gremlingo.T__.OutE().InV()).Times(2).Path().By(\"name\").By(gremlingo.T.Label)",
+ "groovy": "g.V().repeat(__.outE().inV()).times(2).path().by(\"name\").by(T.label)",
+ "java": "g.V().repeat(__.outE().inV()).times(2).path().by(\"name\").by(T.label)",
+ "javascript": "g.V().repeat(__.outE().inV()).times(2).path().by(\"name\").by(T.label)",
+ "python": "g.V().repeat(__.out_e().in_v()).times(2).path().by('name').by(T.label)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXoutX_timesX2X",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.out()).times(2)",
+ "language": "g.V().repeat(__.out()).times(2)",
+ "anonymized": "g.V().repeat(__.out()).times(number0)",
+ "dotnet": "g.V().Repeat(__.Out()).Times(2)",
+ "go": "g.V().Repeat(gremlingo.T__.Out()).Times(2)",
+ "groovy": "g.V().repeat(__.out()).times(2)",
+ "java": "g.V().repeat(__.out()).times(2)",
+ "javascript": "g.V().repeat(__.out()).times(2)",
+ "python": "g.V().repeat(__.out()).times(2)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXoutX_timesX2X_emit",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.out()).times(2).emit()",
+ "language": "g.V().repeat(__.out()).times(2).emit()",
+ "anonymized": "g.V().repeat(__.out()).times(number0).emit()",
+ "dotnet": "g.V().Repeat(__.Out()).Times(2).Emit()",
+ "go": "g.V().Repeat(gremlingo.T__.Out()).Times(2).Emit()",
+ "groovy": "g.V().repeat(__.out()).times(2).emit()",
+ "java": "g.V().repeat(__.out()).times(2).emit()",
+ "javascript": "g.V().repeat(__.out()).times(2).emit()",
+ "python": "g.V().repeat(__.out()).times(2).emit()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_timesX2X_repeatXoutX_name",
+ "traversals": [
+ {
+ "original": "g.V(vid1).times(2).repeat(__.out()).values(\"name\")",
+ "language": "g.V(vid1).times(2).repeat(__.out()).values(\"name\")",
+ "anonymized": "g.V(vid1).times(number0).repeat(__.out()).values(string0)",
+ "dotnet": "g.V(vid1).Times(2).Repeat(__.Out()).Values<object>(\"name\")",
+ "go": "g.V(vid1).Times(2).Repeat(gremlingo.T__.Out()).Values(\"name\")",
+ "groovy": "g.V(vid1).times(2).repeat(__.out()).values(\"name\")",
+ "java": "g.V(vid1).times(2).repeat(__.out()).values(\"name\")",
+ "javascript": "g.V(vid1).times(2).repeat(__.out()).values(\"name\")",
+ "python": "g.V(vid1).times(2).repeat(__.out()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit_timesX2X_repeatXoutX_path",
+ "traversals": [
+ {
+ "original": "g.V().emit().times(2).repeat(__.out()).path()",
+ "language": "g.V().emit().times(2).repeat(__.out()).path()",
+ "anonymized": "g.V().emit().times(number0).repeat(__.out()).path()",
+ "dotnet": "g.V().Emit().Times(2).Repeat(__.Out()).Path()",
+ "go": "g.V().Emit().Times(2).Repeat(gremlingo.T__.Out()).Path()",
+ "groovy": "g.V().emit().times(2).repeat(__.out()).path()",
+ "java": "g.V().emit().times(2).repeat(__.out()).path()",
+ "javascript": "g.V().emit().times(2).repeat(__.out()).path()",
+ "python": "g.V().emit().times(2).repeat(__.out()).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit_repeatXoutX_timesX2X_path",
+ "traversals": [
+ {
+ "original": "g.V().emit().repeat(__.out()).times(2).path()",
+ "language": "g.V().emit().repeat(__.out()).times(2).path()",
+ "anonymized": "g.V().emit().repeat(__.out()).times(number0).path()",
+ "dotnet": "g.V().Emit().Repeat(__.Out()).Times(2).Path()",
+ "go": "g.V().Emit().Repeat(gremlingo.T__.Out()).Times(2).Path()",
+ "groovy": "g.V().emit().repeat(__.out()).times(2).path()",
+ "java": "g.V().emit().repeat(__.out()).times(2).path()",
+ "javascript": "g.V().emit().repeat(__.out()).times(2).path()",
+ "python": "g.V().emit().repeat(__.out()).times(2).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_emitXhasXlabel_personXX_repeatXoutX_name",
+ "traversals": [
+ {
+ "original": "g.V(vid1).emit(__.has(T.label, \"person\")).repeat(__.out()).values(\"name\")",
+ "language": "g.V(vid1).emit(__.has(T.label, \"person\")).repeat(__.out()).values(\"name\")",
+ "anonymized": "g.V(vid1).emit(__.has(T.label, string0)).repeat(__.out()).values(string1)",
+ "dotnet": "g.V(vid1).Emit(__.Has(T.Label, \"person\")).Repeat(__.Out()).Values<object>(\"name\")",
+ "go": "g.V(vid1).Emit(gremlingo.T__.Has(gremlingo.T.Label, \"person\")).Repeat(gremlingo.T__.Out()).Values(\"name\")",
+ "groovy": "g.V(vid1).emit(__.has(T.label, \"person\")).repeat(__.out()).values(\"name\")",
+ "java": "g.V(vid1).emit(__.has(T.label, \"person\")).repeat(__.out()).values(\"name\")",
+ "javascript": "g.V(vid1).emit(__.has(T.label, \"person\")).repeat(__.out()).values(\"name\")",
+ "python": "g.V(vid1).emit(__.has(T.label, 'person')).repeat(__.out()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXgroupCountXmX_byXnameX_outX_timesX2X_capXmX",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.groupCount(\"m\").by(\"name\").out()).times(2).cap(\"m\")",
+ "language": "g.V().repeat(__.groupCount(\"m\").by(\"name\").out()).times(2).cap(\"m\")",
+ "anonymized": "g.V().repeat(__.groupCount(string0).by(string1).out()).times(number0).cap(string0)",
+ "dotnet": "g.V().Repeat(__.GroupCount(\"m\").By(\"name\").Out()).Times(2).Cap<object>(\"m\")",
+ "go": "g.V().Repeat(gremlingo.T__.GroupCount(\"m\").By(\"name\").Out()).Times(2).Cap(\"m\")",
+ "groovy": "g.V().repeat(__.groupCount(\"m\").by(\"name\").out()).times(2).cap(\"m\")",
+ "java": "g.V().repeat(__.groupCount(\"m\").by(\"name\").out()).times(2).cap(\"m\")",
+ "javascript": "g.V().repeat(__.groupCount(\"m\").by(\"name\").out()).times(2).cap(\"m\")",
+ "python": "g.V().repeat(__.group_count('m').by('name').out()).times(2).cap('m')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_repeatXgroupCountXmX_byXloopsX_outX_timesX3X_capXmX",
+ "traversals": [
+ {
+ "original": "g.V(vid1).repeat(__.groupCount(\"m\").by(__.loops()).out()).times(3).cap(\"m\")",
+ "language": "g.V(vid1).repeat(__.groupCount(\"m\").by(__.loops()).out()).times(3).cap(\"m\")",
+ "anonymized": "g.V(vid1).repeat(__.groupCount(string0).by(__.loops()).out()).times(number0).cap(string0)",
+ "dotnet": "g.V(vid1).Repeat(__.GroupCount(\"m\").By(__.Loops()).Out()).Times(3).Cap<object>(\"m\")",
+ "go": "g.V(vid1).Repeat(gremlingo.T__.GroupCount(\"m\").By(gremlingo.T__.Loops()).Out()).Times(3).Cap(\"m\")",
+ "groovy": "g.V(vid1).repeat(__.groupCount(\"m\").by(__.loops()).out()).times(3).cap(\"m\")",
+ "java": "g.V(vid1).repeat(__.groupCount(\"m\").by(__.loops()).out()).times(3).cap(\"m\")",
+ "javascript": "g.V(vid1).repeat(__.groupCount(\"m\").by(__.loops()).out()).times(3).cap(\"m\")",
+ "python": "g.V(vid1).repeat(__.group_count('m').by(__.loops()).out()).times(3).cap('m')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXbothX_timesX10X_asXaX_out_asXbX_selectXa_bX",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.both()).times(10).as(\"a\").out().as(\"b\").select(\"a\", \"b\").count()",
+ "language": "g.V().repeat(__.both()).times(10).as(\"a\").out().as(\"b\").select(\"a\", \"b\").count()",
+ "anonymized": "g.V().repeat(__.both()).times(number0).as(string0).out().as(string1).select(string0, string1).count()",
+ "dotnet": "g.V().Repeat(__.Both()).Times(10).As(\"a\").Out().As(\"b\").Select<object>(\"a\", \"b\").Count()",
+ "go": "g.V().Repeat(gremlingo.T__.Both()).Times(10).As(\"a\").Out().As(\"b\").Select(\"a\", \"b\").Count()",
+ "groovy": "g.V().repeat(__.both()).times(10).as(\"a\").out().as(\"b\").select(\"a\", \"b\").count()",
+ "java": "g.V().repeat(__.both()).times(10).as(\"a\").out().as(\"b\").select(\"a\", \"b\").count()",
+ "javascript": "g.V().repeat(__.both()).times(10).as(\"a\").out().as(\"b\").select(\"a\", \"b\").count()",
+ "python": "g.V().repeat(__.both()).times(10).as_('a').out().as_('b').select('a', 'b').count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_repeatXoutX_untilXoutE_count_isX0XX_name",
+ "traversals": [
+ {
+ "original": "g.V(vid1).repeat(__.out()).until(__.outE().count().is(0)).values(\"name\")",
+ "language": "g.V(vid1).repeat(__.out()).until(__.outE().count().is(0)).values(\"name\")",
+ "anonymized": "g.V(vid1).repeat(__.out()).until(__.outE().count().is(number0)).values(string0)",
+ "dotnet": "g.V(vid1).Repeat(__.Out()).Until(__.OutE().Count().Is(0)).Values<object>(\"name\")",
+ "go": "g.V(vid1).Repeat(gremlingo.T__.Out()).Until(gremlingo.T__.OutE().Count().Is(0)).Values(\"name\")",
+ "groovy": "g.V(vid1).repeat(__.out()).until(__.outE().count().is(0)).values(\"name\")",
+ "java": "g.V(vid1).repeat(__.out()).until(__.outE().count().is(0)).values(\"name\")",
+ "javascript": "g.V(vid1).repeat(__.out()).until(__.outE().count().is(0)).values(\"name\")",
+ "python": "g.V(vid1).repeat(__.out()).until(__.out_e().count().is_(0)).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXname_markoX_repeatXoutE_inV_simplePathX_untilXhasXname_rippleXX_path_byXnameX_byXlabelX",
+ "traversals": [
+ {
+ "original": "g.V().has(\"name\", \"marko\").repeat(__.outE().inV().simplePath()).until(__.has(\"name\", \"ripple\")).path().by(\"name\").by(T.label)",
+ "language": "g.V().has(\"name\", \"marko\").repeat(__.outE().inV().simplePath()).until(__.has(\"name\", \"ripple\")).path().by(\"name\").by(T.label)",
+ "anonymized": "g.V().has(string0, string1).repeat(__.outE().inV().simplePath()).until(__.has(string0, string2)).path().by(string0).by(T.label)",
+ "dotnet": "g.V().Has(\"name\", \"marko\").Repeat(__.OutE().InV().SimplePath()).Until(__.Has(\"name\", \"ripple\")).Path().By(\"name\").By(T.Label)",
+ "go": "g.V().Has(\"name\", \"marko\").Repeat(gremlingo.T__.OutE().InV().SimplePath()).Until(gremlingo.T__.Has(\"name\", \"ripple\")).Path().By(\"name\").By(gremlingo.T.Label)",
+ "groovy": "g.V().has(\"name\", \"marko\").repeat(__.outE().inV().simplePath()).until(__.has(\"name\", \"ripple\")).path().by(\"name\").by(T.label)",
+ "java": "g.V().has(\"name\", \"marko\").repeat(__.outE().inV().simplePath()).until(__.has(\"name\", \"ripple\")).path().by(\"name\").by(T.label)",
+ "javascript": "g.V().has(\"name\", \"marko\").repeat(__.outE().inV().simplePath()).until(__.has(\"name\", \"ripple\")).path().by(\"name\").by(T.label)",
+ "python": "g.V().has('name', 'marko').repeat(__.out_e().in_v().simple_path()).until(__.has('name', 'ripple')).path().by('name').by(T.label)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXloop_name_loopX_repeatXinX_timesX5X_path_by_name",
+ "traversals": [
+ {
+ "original": "g.V().has(\"loops\",\"name\",\"loop\").repeat(__.in()).times(5).path().by(\"name\")",
+ "language": "g.V().has(\"loops\", \"name\", \"loop\").repeat(__.in()).times(5).path().by(\"name\")",
+ "anonymized": "g.V().has(string0, string1, string2).repeat(__.in()).times(number0).path().by(string1)",
+ "dotnet": "g.V().Has(\"loops\", \"name\", \"loop\").Repeat(__.In()).Times(5).Path().By(\"name\")",
+ "go": "g.V().Has(\"loops\", \"name\", \"loop\").Repeat(gremlingo.T__.In()).Times(5).Path().By(\"name\")",
+ "groovy": "g.V().has(\"loops\", \"name\", \"loop\").repeat(__.in()).times(5).path().by(\"name\")",
+ "java": "g.V().has(\"loops\", \"name\", \"loop\").repeat(__.in()).times(5).path().by(\"name\")",
+ "javascript": "g.V().has(\"loops\", \"name\", \"loop\").repeat(__.in_()).times(5).path().by(\"name\")",
+ "python": "g.V().has('loops', 'name', 'loop').repeat(__.in_()).times(5).path().by('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXout_repeatXout_order_byXname_descXX_timesX1XX_timesX1X_limitX1X_path_byXnameX",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.out().repeat(__.out().order().by(\"name\",desc)).times(1)).times(1).limit(1).path().by(\"name\")",
+ "language": "g.V().repeat(__.out().repeat(__.out().order().by(\"name\", Order.desc)).times(1)).times(1).limit(1).path().by(\"name\")",
+ "anonymized": "g.V().repeat(__.out().repeat(__.out().order().by(string0, Order.desc)).times(number0)).times(number0).limit(number0).path().by(string0)",
+ "dotnet": "g.V().Repeat(__.Out().Repeat(__.Out().Order().By(\"name\", Order.Desc)).Times(1)).Times(1).Limit<object>(1).Path().By(\"name\")",
+ "go": "g.V().Repeat(gremlingo.T__.Out().Repeat(gremlingo.T__.Out().Order().By(\"name\", gremlingo.Order.Desc)).Times(1)).Times(1).Limit(1).Path().By(\"name\")",
+ "groovy": "g.V().repeat(__.out().repeat(__.out().order().by(\"name\", Order.desc)).times(1)).times(1).limit(1).path().by(\"name\")",
+ "java": "g.V().repeat(__.out().repeat(__.out().order().by(\"name\", Order.desc)).times(1)).times(1).limit(1).path().by(\"name\")",
+ "javascript": "g.V().repeat(__.out().repeat(__.out().order().by(\"name\", Order.desc)).times(1)).times(1).limit(1).path().by(\"name\")",
+ "python": "g.V().repeat(__.out().repeat(__.out().order().by('name', Order.desc)).times(1)).times(1).limit(1).path().by('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXoutXknowsXX_untilXrepeatXoutXcreatedXX_emitXhasXname_lopXXX_path_byXnameX",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.out(\"knows\")).until(__.repeat(__.out(\"created\")).emit(__.has(\"name\", \"lop\"))).path().by(\"name\")",
+ "language": "g.V().repeat(__.out(\"knows\")).until(__.repeat(__.out(\"created\")).emit(__.has(\"name\", \"lop\"))).path().by(\"name\")",
+ "anonymized": "g.V().repeat(__.out(string0)).until(__.repeat(__.out(string1)).emit(__.has(string2, string3))).path().by(string2)",
+ "dotnet": "g.V().Repeat(__.Out(\"knows\")).Until(__.Repeat(__.Out(\"created\")).Emit(__.Has(\"name\", \"lop\"))).Path().By(\"name\")",
+ "go": "g.V().Repeat(gremlingo.T__.Out(\"knows\")).Until(gremlingo.T__.Repeat(gremlingo.T__.Out(\"created\")).Emit(gremlingo.T__.Has(\"name\", \"lop\"))).Path().By(\"name\")",
+ "groovy": "g.V().repeat(__.out(\"knows\")).until(__.repeat(__.out(\"created\")).emit(__.has(\"name\", \"lop\"))).path().by(\"name\")",
+ "java": "g.V().repeat(__.out(\"knows\")).until(__.repeat(__.out(\"created\")).emit(__.has(\"name\", \"lop\"))).path().by(\"name\")",
+ "javascript": "g.V().repeat(__.out(\"knows\")).until(__.repeat(__.out(\"created\")).emit(__.has(\"name\", \"lop\"))).path().by(\"name\")",
+ "python": "g.V().repeat(__.out('knows')).until(__.repeat(__.out('created')).emit(__.has('name', 'lop'))).path().by('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXrepeatXout_createdXX_untilXhasXname_rippleXXXemit_lang",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "language": "g.V().repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "anonymized": "g.V().repeat(__.repeat(__.out(string0)).until(__.has(string1, string2))).emit().values(string3)",
+ "dotnet": "g.V().Repeat(__.Repeat(__.Out(\"created\")).Until(__.Has(\"name\", \"ripple\"))).Emit().Values<object>(\"lang\")",
+ "go": "g.V().Repeat(gremlingo.T__.Repeat(gremlingo.T__.Out(\"created\")).Until(gremlingo.T__.Has(\"name\", \"ripple\"))).Emit().Values(\"lang\")",
+ "groovy": "g.V().repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "java": "g.V().repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "javascript": "g.V().repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "python": "g.V().repeat(__.repeat(__.out('created')).until(__.has('name', 'ripple'))).emit().values('lang')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_untilXconstantXtrueXX_repeatXrepeatXout_createdXX_untilXhasXname_rippleXXXemit_lang",
+ "traversals": [
+ {
+ "original": "g.V().until(__.constant(true)).repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "language": "g.V().until(__.constant(true)).repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "anonymized": "g.V().until(__.constant(boolean0)).repeat(__.repeat(__.out(string0)).until(__.has(string1, string2))).emit().values(string3)",
+ "dotnet": "g.V().Until(__.Constant<object>(true)).Repeat(__.Repeat(__.Out(\"created\")).Until(__.Has(\"name\", \"ripple\"))).Emit().Values<object>(\"lang\")",
+ "go": "g.V().Until(gremlingo.T__.Constant(true)).Repeat(gremlingo.T__.Repeat(gremlingo.T__.Out(\"created\")).Until(gremlingo.T__.Has(\"name\", \"ripple\"))).Emit().Values(\"lang\")",
+ "groovy": "g.V().until(__.constant(true)).repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "java": "g.V().until(__.constant(true)).repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "javascript": "g.V().until(__.constant(true)).repeat(__.repeat(__.out(\"created\")).until(__.has(\"name\", \"ripple\"))).emit().values(\"lang\")",
+ "python": "g.V().until(__.constant(True)).repeat(__.repeat(__.out('created')).until(__.has('name', 'ripple'))).emit().values('lang')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit_repeatXa_outXknows_filterXloops_isX0XX_lang",
+ "traversals": [
+ {
+ "original": "g.V().emit().repeat(\"a\", __.out(\"knows\").filter(__.loops(\"a\").is(0))).values(\"lang\")",
+ "language": "g.V().emit().repeat(\"a\", __.out(\"knows\").filter(__.loops(\"a\").is(0))).values(\"lang\")",
+ "anonymized": "g.V().emit().repeat(string0, __.out(string1).filter(__.loops(string0).is(number0))).values(string2)",
+ "dotnet": "g.V().Emit().Repeat(\"a\", __.Out(\"knows\").Filter(__.Loops(\"a\").Is(0))).Values<object>(\"lang\")",
+ "go": "g.V().Emit().Repeat(\"a\", gremlingo.T__.Out(\"knows\").Filter(gremlingo.T__.Loops(\"a\").Is(0))).Values(\"lang\")",
+ "groovy": "g.V().emit().repeat(\"a\", __.out(\"knows\").filter(__.loops(\"a\").is(0))).values(\"lang\")",
+ "java": "g.V().emit().repeat(\"a\", __.out(\"knows\").filter(__.loops(\"a\").is(0))).values(\"lang\")",
+ "javascript": "g.V().emit().repeat(\"a\", __.out(\"knows\").filter(__.loops(\"a\").is(0))).values(\"lang\")",
+ "python": "g.V().emit().repeat('a', __.out('knows').filter_(__.loops('a').is_(0))).values('lang')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX3X_repeatXbothX_createdXX_untilXloops_is_40XXemit_repeatXin_knowsXX_emit_loopsXisX1Xdedup_values",
+ "traversals": [
+ {
+ "original": "g.V(vid3).repeat(__.both(\"created\")).until(__.loops().is(40)).emit(__.repeat(__.in(\"knows\")).emit(__.loops().is(1))).dedup().values(\"name\")",
+ "language": "g.V(vid3).repeat(__.both(\"created\")).until(__.loops().is(40)).emit(__.repeat(__.in(\"knows\")).emit(__.loops().is(1))).dedup().values(\"name\")",
+ "anonymized": "g.V(vid3).repeat(__.both(string0)).until(__.loops().is(number0)).emit(__.repeat(__.in(string1)).emit(__.loops().is(number1))).dedup().values(string2)",
+ "dotnet": "g.V(vid3).Repeat(__.Both(\"created\")).Until(__.Loops().Is(40)).Emit(__.Repeat(__.In(\"knows\")).Emit(__.Loops().Is(1))).Dedup().Values<object>(\"name\")",
+ "go": "g.V(vid3).Repeat(gremlingo.T__.Both(\"created\")).Until(gremlingo.T__.Loops().Is(40)).Emit(gremlingo.T__.Repeat(gremlingo.T__.In(\"knows\")).Emit(gremlingo.T__.Loops().Is(1))).Dedup().Values(\"name\")",
+ "groovy": "g.V(vid3).repeat(__.both(\"created\")).until(__.loops().is(40)).emit(__.repeat(__.in(\"knows\")).emit(__.loops().is(1))).dedup().values(\"name\")",
+ "java": "g.V(vid3).repeat(__.both(\"created\")).until(__.loops().is(40)).emit(__.repeat(__.in(\"knows\")).emit(__.loops().is(1))).dedup().values(\"name\")",
+ "javascript": "g.V(vid3).repeat(__.both(\"created\")).until(__.loops().is(40)).emit(__.repeat(__.in_(\"knows\")).emit(__.loops().is(1))).dedup().values(\"name\")",
+ "python": "g.V(vid3).repeat(__.both('created')).until(__.loops().is_(40)).emit(__.repeat(__.in_('knows')).emit(__.loops().is_(1))).dedup().values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_repeatXrepeatXunionXout_uses_out_traversesXX_whereXloops_isX0X_timesX1X_timeX2X_name",
+ "traversals": [
+ {
+ "original": "g.V(vid1).repeat(__.repeat(__.union(__.out(\"uses\"), __.out(\"traverses\")).where(__.loops().is(0))).times(1)).times(2).values(\"name\")",
+ "language": "g.V(vid1).repeat(__.repeat(__.union(__.out(\"uses\"), __.out(\"traverses\")).where(__.loops().is(0))).times(1)).times(2).values(\"name\")",
+ "anonymized": "g.V(vid1).repeat(__.repeat(__.union(__.out(string0), __.out(string1)).where(__.loops().is(number0))).times(number1)).times(number2).values(string2)",
+ "dotnet": "g.V(vid1).Repeat(__.Repeat(__.Union<object>(__.Out(\"uses\"), __.Out(\"traverses\")).Where(__.Loops().Is(0))).Times(1)).Times(2).Values<object>(\"name\")",
+ "go": "g.V(vid1).Repeat(gremlingo.T__.Repeat(gremlingo.T__.Union(gremlingo.T__.Out(\"uses\"), gremlingo.T__.Out(\"traverses\")).Where(gremlingo.T__.Loops().Is(0))).Times(1)).Times(2).Values(\"name\")",
+ "groovy": "g.V(vid1).repeat(__.repeat(__.union(__.out(\"uses\"), __.out(\"traverses\")).where(__.loops().is(0))).times(1)).times(2).values(\"name\")",
+ "java": "g.V(vid1).repeat(__.repeat(__.union(__.out(\"uses\"), __.out(\"traverses\")).where(__.loops().is(0))).times(1)).times(2).values(\"name\")",
+ "javascript": "g.V(vid1).repeat(__.repeat(__.union(__.out(\"uses\"), __.out(\"traverses\")).where(__.loops().is(0))).times(1)).times(2).values(\"name\")",
+ "python": "g.V(vid1).repeat(__.repeat(__.union(__.out('uses'), __.out('traverses')).where(__.loops().is_(0))).times(1)).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXa_outXknows_repeatXb_outXcreatedX_filterXloops_isX0XX_emit_lang",
+ "traversals": [
+ {
+ "original": "g.V().repeat(\"a\", __.out(\"knows\").repeat(\"b\", __.out(\"created\").filter(__.loops(\"a\").is(0))).emit()).emit().values(\"lang\")",
+ "language": "g.V().repeat(\"a\", __.out(\"knows\").repeat(\"b\", __.out(\"created\").filter(__.loops(\"a\").is(0))).emit()).emit().values(\"lang\")",
+ "anonymized": "g.V().repeat(string0, __.out(string1).repeat(string2, __.out(string3).filter(__.loops(string0).is(number0))).emit()).emit().values(string4)",
+ "dotnet": "g.V().Repeat(\"a\", __.Out(\"knows\").Repeat(\"b\", __.Out(\"created\").Filter(__.Loops(\"a\").Is(0))).Emit()).Emit().Values<object>(\"lang\")",
+ "go": "g.V().Repeat(\"a\", gremlingo.T__.Out(\"knows\").Repeat(\"b\", gremlingo.T__.Out(\"created\").Filter(gremlingo.T__.Loops(\"a\").Is(0))).Emit()).Emit().Values(\"lang\")",
+ "groovy": "g.V().repeat(\"a\", __.out(\"knows\").repeat(\"b\", __.out(\"created\").filter(__.loops(\"a\").is(0))).emit()).emit().values(\"lang\")",
+ "java": "g.V().repeat(\"a\", __.out(\"knows\").repeat(\"b\", __.out(\"created\").filter(__.loops(\"a\").is(0))).emit()).emit().values(\"lang\")",
+ "javascript": "g.V().repeat(\"a\", __.out(\"knows\").repeat(\"b\", __.out(\"created\").filter(__.loops(\"a\").is(0))).emit()).emit().values(\"lang\")",
+ "python": "g.V().repeat('a', __.out('knows').repeat('b', __.out('created').filter_(__.loops('a').is_(0))).emit()).emit().values('lang')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX6X_repeatXa_bothXcreatedX_simplePathX_emitXrepeatXb_bothXknowsXX_untilXloopsXbX_asXb_whereXloopsXaX_asXbX_hasXname_vadasXX_dedup_name",
+ "traversals": [
+ {
+ "original": "g.V(vid6).repeat(\"a\", __.both(\"created\").simplePath()).emit(__.repeat(\"b\", __.both(\"knows\")).until(__.loops(\"b\").as(\"b\").where(__.loops(\"a\").as(\"b\"))).has(\"name\", \"vadas\")).dedup().values(\"name\")",
+ "language": "g.V(vid6).repeat(\"a\", __.both(\"created\").simplePath()).emit(__.repeat(\"b\", __.both(\"knows\")).until(__.loops(\"b\").as(\"b\").where(__.loops(\"a\").as(\"b\"))).has(\"name\", \"vadas\")).dedup().values(\"name\")",
+ "anonymized": "g.V(vid6).repeat(string0, __.both(string1).simplePath()).emit(__.repeat(string2, __.both(string3)).until(__.loops(string2).as(string2).where(__.loops(string0).as(string2))).has(string4, string5)).dedup().values(string4)",
+ "dotnet": "g.V(vid6).Repeat(\"a\", __.Both(\"created\").SimplePath()).Emit(__.Repeat(\"b\", __.Both(\"knows\")).Until(__.Loops(\"b\").As(\"b\").Where(__.Loops(\"a\").As(\"b\"))).Has(\"name\", \"vadas\")).Dedup().Values<object>(\"name\")",
+ "go": "g.V(vid6).Repeat(\"a\", gremlingo.T__.Both(\"created\").SimplePath()).Emit(gremlingo.T__.Repeat(\"b\", gremlingo.T__.Both(\"knows\")).Until(gremlingo.T__.Loops(\"b\").As(\"b\").Where(gremlingo.T__.Loops(\"a\").As(\"b\"))).Has(\"name\", \"vadas\")).Dedup().Values(\"name\")",
+ "groovy": "g.V(vid6).repeat(\"a\", __.both(\"created\").simplePath()).emit(__.repeat(\"b\", __.both(\"knows\")).until(__.loops(\"b\").as(\"b\").where(__.loops(\"a\").as(\"b\"))).has(\"name\", \"vadas\")).dedup().values(\"name\")",
+ "java": "g.V(vid6).repeat(\"a\", __.both(\"created\").simplePath()).emit(__.repeat(\"b\", __.both(\"knows\")).until(__.loops(\"b\").as(\"b\").where(__.loops(\"a\").as(\"b\"))).has(\"name\", \"vadas\")).dedup().values(\"name\")",
+ "javascript": "g.V(vid6).repeat(\"a\", __.both(\"created\").simplePath()).emit(__.repeat(\"b\", __.both(\"knows\")).until(__.loops(\"b\").as(\"b\").where(__.loops(\"a\").as(\"b\"))).has(\"name\", \"vadas\")).dedup().values(\"name\")",
+ "python": "g.V(vid6).repeat('a', __.both('created').simple_path()).emit(__.repeat('b', __.both('knows')).until(__.loops('b').as_('b').where(__.loops('a').as_('b'))).has('name', 'vadas')).dedup().values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit",
+ "traversals": [
+ {
+ "original": "g.V().emit()",
+ "language": "g.V().emit()",
+ "anonymized": "g.V().emit()",
+ "dotnet": "g.V().Emit()",
+ "go": "g.V().Emit()",
+ "groovy": "g.V().emit()",
+ "java": "g.V().emit()",
+ "javascript": "g.V().emit()",
+ "python": "g.V().emit()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_untilXidentityX",
+ "traversals": [
+ {
+ "original": "g.V().until(__.identity())",
+ "language": "g.V().until(__.identity())",
+ "anonymized": "g.V().until(__.identity())",
+ "dotnet": "g.V().Until(__.Identity())",
+ "go": "g.V().Until(gremlingo.T__.Identity())",
+ "groovy": "g.V().until(__.identity())",
+ "java": "g.V().until(__.identity())",
+ "javascript": "g.V().until(__.identity())",
+ "python": "g.V().until(__.identity())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_timesX5X",
+ "traversals": [
+ {
+ "original": "g.V().times(5)",
+ "language": "g.V().times(5)",
+ "anonymized": "g.V().times(number0)",
+ "dotnet": "g.V().Times(5)",
+ "go": "g.V().Times(5)",
+ "groovy": "g.V().times(5)",
+ "java": "g.V().times(5)",
+ "javascript": "g.V().times(5)",
+ "python": "g.V().times(5)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXperson_name_markoX_repeatXoutXcreatedXX_timesX1X_name",
+ "traversals": [
+ {
+ "original": "g.V().has(\"person\",\"name\",\"marko\").repeat(__.out(\"created\")).times(1).values(\"name\")",
+ "language": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(1).values(\"name\")",
+ "anonymized": "g.V().has(string0, string1, string2).repeat(__.out(string3)).times(number0).values(string1)",
+ "dotnet": "g.V().Has(\"person\", \"name\", \"marko\").Repeat(__.Out(\"created\")).Times(1).Values<object>(\"name\")",
+ "go": "g.V().Has(\"person\", \"name\", \"marko\").Repeat(gremlingo.T__.Out(\"created\")).Times(1).Values(\"name\")",
+ "groovy": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(1).values(\"name\")",
+ "java": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(1).values(\"name\")",
+ "javascript": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(1).values(\"name\")",
+ "python": "g.V().has('person', 'name', 'marko').repeat(__.out('created')).times(1).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXperson_name_markoX_repeatXoutXcreatedXX_timesX0X_name",
+ "traversals": [
+ {
+ "original": "g.V().has(\"person\",\"name\",\"marko\").repeat(out(\"created\")).times(0).values(\"name\")",
+ "language": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(0).values(\"name\")",
+ "anonymized": "g.V().has(string0, string1, string2).repeat(__.out(string3)).times(number0).values(string1)",
+ "dotnet": "g.V().Has(\"person\", \"name\", \"marko\").Repeat(__.Out(\"created\")).Times(0).Values<object>(\"name\")",
+ "go": "g.V().Has(\"person\", \"name\", \"marko\").Repeat(gremlingo.T__.Out(\"created\")).Times(0).Values(\"name\")",
+ "groovy": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(0).values(\"name\")",
+ "java": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(0).values(\"name\")",
+ "javascript": "g.V().has(\"person\", \"name\", \"marko\").repeat(__.out(\"created\")).times(0).values(\"name\")",
+ "python": "g.V().has('person', 'name', 'marko').repeat(__.out('created')).times(0).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXperson_name_markoX_timesX1X_repeatXoutXcreatedXX_name",
+ "traversals": [
+ {
+ "original": "g.V().has(\"person\",\"name\",\"marko\").times(1).repeat(out(\"created\")).values(\"name\")",
+ "language": "g.V().has(\"person\", \"name\", \"marko\").times(1).repeat(__.out(\"created\")).values(\"name\")",
+ "anonymized": "g.V().has(string0, string1, string2).times(number0).repeat(__.out(string3)).values(string1)",
+ "dotnet": "g.V().Has(\"person\", \"name\", \"marko\").Times(1).Repeat(__.Out(\"created\")).Values<object>(\"name\")",
+ "go": "g.V().Has(\"person\", \"name\", \"marko\").Times(1).Repeat(gremlingo.T__.Out(\"created\")).Values(\"name\")",
+ "groovy": "g.V().has(\"person\", \"name\", \"marko\").times(1).repeat(__.out(\"created\")).values(\"name\")",
+ "java": "g.V().has(\"person\", \"name\", \"marko\").times(1).repeat(__.out(\"created\")).values(\"name\")",
+ "javascript": "g.V().has(\"person\", \"name\", \"marko\").times(1).repeat(__.out(\"created\")).values(\"name\")",
+ "python": "g.V().has('person', 'name', 'marko').times(1).repeat(__.out('created')).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXperson_name_markoX_timesX0X_repeatXoutXcreatedXX_name",
+ "traversals": [
+ {
+ "original": "g.V().has(\"person\",\"name\",\"marko\").times(0).repeat(out(\"created\")).values(\"name\")",
+ "language": "g.V().has(\"person\", \"name\", \"marko\").times(0).repeat(__.out(\"created\")).values(\"name\")",
+ "anonymized": "g.V().has(string0, string1, string2).times(number0).repeat(__.out(string3)).values(string1)",
+ "dotnet": "g.V().Has(\"person\", \"name\", \"marko\").Times(0).Repeat(__.Out(\"created\")).Values<object>(\"name\")",
+ "go": "g.V().Has(\"person\", \"name\", \"marko\").Times(0).Repeat(gremlingo.T__.Out(\"created\")).Values(\"name\")",
+ "groovy": "g.V().has(\"person\", \"name\", \"marko\").times(0).repeat(__.out(\"created\")).values(\"name\")",
+ "java": "g.V().has(\"person\", \"name\", \"marko\").times(0).repeat(__.out(\"created\")).values(\"name\")",
+ "javascript": "g.V().has(\"person\", \"name\", \"marko\").times(0).repeat(__.out(\"created\")).values(\"name\")",
+ "python": "g.V().has('person', 'name', 'marko').times(0).repeat(__.out('created')).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXboth_hasXnot_productiveXX_timesX3X_constantX1X",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.both().has(\"not\", \"productive\")).times(3).constant(1)",
+ "language": "g.V().repeat(__.both().has(\"not\", \"productive\")).times(3).constant(1)",
+ "anonymized": "g.V().repeat(__.both().has(string0, string1)).times(number0).constant(number1)",
+ "dotnet": "g.V().Repeat(__.Both().Has(\"not\", \"productive\")).Times(3).Constant<object>(1)",
+ "go": "g.V().Repeat(gremlingo.T__.Both().Has(\"not\", \"productive\")).Times(3).Constant(1)",
+ "groovy": "g.V().repeat(__.both().has(\"not\", \"productive\")).times(3).constant(1)",
+ "java": "g.V().repeat(__.both().has(\"not\", \"productive\")).times(3).constant(1)",
+ "javascript": "g.V().repeat(__.both().has(\"not\", \"productive\")).times(3).constant(1)",
+ "python": "g.V().repeat(__.both().has('not', 'productive')).times(3).constant(1)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXnot_productiveX_repeatXbothX_timesX3X_constantX1X",
+ "traversals": [
+ {
+ "original": "g.V().has(\"not\", \"productive\").repeat(__.both()).times(3).constant(1)",
+ "language": "g.V().has(\"not\", \"productive\").repeat(__.both()).times(3).constant(1)",
+ "anonymized": "g.V().has(string0, string1).repeat(__.both()).times(number0).constant(number1)",
+ "dotnet": "g.V().Has(\"not\", \"productive\").Repeat(__.Both()).Times(3).Constant<object>(1)",
+ "go": "g.V().Has(\"not\", \"productive\").Repeat(gremlingo.T__.Both()).Times(3).Constant(1)",
+ "groovy": "g.V().has(\"not\", \"productive\").repeat(__.both()).times(3).constant(1)",
+ "java": "g.V().has(\"not\", \"productive\").repeat(__.both()).times(3).constant(1)",
+ "javascript": "g.V().has(\"not\", \"productive\").repeat(__.both()).times(3).constant(1)",
+ "python": "g.V().has('not', 'productive').repeat(__.both()).times(3).constant(1)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1_2_3X_repeatXboth_barrierX_emit_timesX2X_path",
+ "traversals": [
+ {
+ "original": "g.V(vid1, vid2, vid3).repeat(__.both().barrier()).emit().times(2).path()",
+ "language": "g.V(vid1, vid2, vid3).repeat(__.both().barrier()).emit().times(2).path()",
+ "anonymized": "g.V(vid1, vid2, vid3).repeat(__.both().barrier()).emit().times(number0).path()",
+ "dotnet": "g.V(vid1, vid2, vid3).Repeat(__.Both().Barrier()).Emit().Times(2).Path()",
+ "go": "g.V(vid1, vid2, vid3).Repeat(gremlingo.T__.Both().Barrier()).Emit().Times(2).Path()",
+ "groovy": "g.V(vid1, vid2, vid3).repeat(__.both().barrier()).emit().times(2).path()",
+ "java": "g.V(vid1, vid2, vid3).repeat(__.both().barrier()).emit().times(2).path()",
+ "javascript": "g.V(vid1, vid2, vid3).repeat(__.both().barrier()).emit().times(2).path()",
+ "python": "g.V(vid1, vid2, vid3).repeat(__.both().barrier()).emit().times(2).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_order_byXname_descX_repeatXboth_simplePath_order_byXname_descXX_timesX2X_path",
+ "traversals": [
+ {
+ "original": "g.V().order().by(\"name\", Order.desc).repeat(__.both().simplePath().order().by(\"name\", Order.desc)).times(2).path()",
+ "language": "g.V().order().by(\"name\", Order.desc).repeat(__.both().simplePath().order().by(\"name\", Order.desc)).times(2).path()",
+ "anonymized": "g.V().order().by(string0, Order.desc).repeat(__.both().simplePath().order().by(string0, Order.desc)).times(number0).path()",
+ "dotnet": "g.V().Order().By(\"name\", Order.Desc).Repeat(__.Both().SimplePath().Order().By(\"name\", Order.Desc)).Times(2).Path()",
+ "go": "g.V().Order().By(\"name\", gremlingo.Order.Desc).Repeat(gremlingo.T__.Both().SimplePath().Order().By(\"name\", gremlingo.Order.Desc)).Times(2).Path()",
+ "groovy": "g.V().order().by(\"name\", Order.desc).repeat(__.both().simplePath().order().by(\"name\", Order.desc)).times(2).path()",
+ "java": "g.V().order().by(\"name\", Order.desc).repeat(__.both().simplePath().order().by(\"name\", Order.desc)).times(2).path()",
+ "javascript": "g.V().order().by(\"name\", Order.desc).repeat(__.both().simplePath().order().by(\"name\", Order.desc)).times(2).path()",
+ "python": "g.V().order().by('name', Order.desc).repeat(__.both().simple_path().order().by('name', Order.desc)).times(2).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXboth_repeatXorder_byXnameXX_timesX1XX_timesX1X",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.both().repeat(__.order().by(\"name\")).times(1)).times(1)",
+ "language": "g.V().repeat(__.both().repeat(__.order().by(\"name\")).times(1)).times(1)",
+ "anonymized": "g.V().repeat(__.both().repeat(__.order().by(string0)).times(number0)).times(number0)",
+ "dotnet": "g.V().Repeat(__.Both().Repeat(__.Order().By(\"name\")).Times(1)).Times(1)",
+ "go": "g.V().Repeat(gremlingo.T__.Both().Repeat(gremlingo.T__.Order().By(\"name\")).Times(1)).Times(1)",
+ "groovy": "g.V().repeat(__.both().repeat(__.order().by(\"name\")).times(1)).times(1)",
+ "java": "g.V().repeat(__.both().repeat(__.order().by(\"name\")).times(1)).times(1)",
+ "javascript": "g.V().repeat(__.both().repeat(__.order().by(\"name\")).times(1)).times(1)",
+ "python": "g.V().repeat(__.both().repeat(__.order().by('name')).times(1)).times(1)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_order_byXname_descX_repeatXlocalXout_order_byXnameXXX_timesX1X",
+ "traversals": [
+ {
+ "original": "g.V().order().by(\"name\", Order.desc).repeat(__.local(__.out().order().by(\"name\"))).times(1)",
+ "language": "g.V().order().by(\"name\", Order.desc).repeat(__.local(__.out().order().by(\"name\"))).times(1)",
+ "anonymized": "g.V().order().by(string0, Order.desc).repeat(__.local(__.out().order().by(string0))).times(number0)",
+ "dotnet": "g.V().Order().By(\"name\", Order.Desc).Repeat(__.Local<object>(__.Out().Order().By(\"name\"))).Times(1)",
+ "go": "g.V().Order().By(\"name\", gremlingo.Order.Desc).Repeat(gremlingo.T__.Local(gremlingo.T__.Out().Order().By(\"name\"))).Times(1)",
+ "groovy": "g.V().order().by(\"name\", Order.desc).repeat(__.local(__.out().order().by(\"name\"))).times(1)",
+ "java": "g.V().order().by(\"name\", Order.desc).repeat(__.local(__.out().order().by(\"name\"))).times(1)",
+ "javascript": "g.V().order().by(\"name\", Order.desc).repeat(__.local(__.out().order().by(\"name\"))).times(1)",
+ "python": "g.V().order().by('name', Order.desc).repeat(__.local(__.out().order().by('name'))).times(1)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_order_byXnameX_repeatXlocalXboth_simplePath_order_byXnameXXX_timesX2X_path",
+ "traversals": [
+ {
+ "original": "g.V().order().by(\"name\").repeat(__.local(__.both().simplePath().order().by(\"name\"))).times(2).path()",
+ "language": "g.V().order().by(\"name\").repeat(__.local(__.both().simplePath().order().by(\"name\"))).times(2).path()",
+ "anonymized": "g.V().order().by(string0).repeat(__.local(__.both().simplePath().order().by(string0))).times(number0).path()",
+ "dotnet": "g.V().Order().By(\"name\").Repeat(__.Local<object>(__.Both().SimplePath().Order().By(\"name\"))).Times(2).Path()",
+ "go": "g.V().Order().By(\"name\").Repeat(gremlingo.T__.Local(gremlingo.T__.Both().SimplePath().Order().By(\"name\"))).Times(2).Path()",
+ "groovy": "g.V().order().by(\"name\").repeat(__.local(__.both().simplePath().order().by(\"name\"))).times(2).path()",
+ "java": "g.V().order().by(\"name\").repeat(__.local(__.both().simplePath().order().by(\"name\"))).times(2).path()",
+ "javascript": "g.V().order().by(\"name\").repeat(__.local(__.both().simplePath().order().by(\"name\"))).times(2).path()",
+ "python": "g.V().order().by('name').repeat(__.local(__.both().simple_path().order().by('name'))).times(2).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXunionXoutXknowsX_order_byXnameX_inXcreatedX_order_byXnameXXX_timesX1X",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.union(__.out(\"knows\").order().by(\"name\"), __.in(\"created\").order().by(\"name\"))).times(1)",
+ "language": "g.V().repeat(__.union(__.out(\"knows\").order().by(\"name\"), __.in(\"created\").order().by(\"name\"))).times(1)",
+ "anonymized": "g.V().repeat(__.union(__.out(string0).order().by(string1), __.in(string2).order().by(string1))).times(number0)",
+ "dotnet": "g.V().Repeat(__.Union<object>(__.Out(\"knows\").Order().By(\"name\"), __.In(\"created\").Order().By(\"name\"))).Times(1)",
+ "go": "g.V().Repeat(gremlingo.T__.Union(gremlingo.T__.Out(\"knows\").Order().By(\"name\"), gremlingo.T__.In(\"created\").Order().By(\"name\"))).Times(1)",
+ "groovy": "g.V().repeat(__.union(__.out(\"knows\").order().by(\"name\"), __.in(\"created\").order().by(\"name\"))).times(1)",
+ "java": "g.V().repeat(__.union(__.out(\"knows\").order().by(\"name\"), __.in(\"created\").order().by(\"name\"))).times(1)",
+ "javascript": "g.V().repeat(__.union(__.out(\"knows\").order().by(\"name\"), __.in_(\"created\").order().by(\"name\"))).times(1)",
+ "python": "g.V().repeat(__.union(__.out('knows').order().by('name'), __.in_('created').order().by('name'))).times(1)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXaddV_propertyXgenerated_trueXX_timesX2X",
+ "traversals": [
+ {
+ "original": "g.addV().property(\"notGenerated\", \"true\").addV().property(\"notGenerated\", \"true\")",
+ "language": "g.addV().property(\"notGenerated\", \"true\").addV().property(\"notGenerated\", \"true\")",
+ "anonymized": "g.addV().property(string0, string1).addV().property(string0, string1)",
+ "dotnet": "g.AddV().Property(\"notGenerated\", \"true\").AddV().Property(\"notGenerated\", \"true\")",
+ "go": "g.AddV().Property(\"notGenerated\", \"true\").AddV().Property(\"notGenerated\", \"true\")",
+ "groovy": "g.addV().property(\"notGenerated\", \"true\").addV().property(\"notGenerated\", \"true\")",
+ "java": "g.addV().property(\"notGenerated\", \"true\").addV().property(\"notGenerated\", \"true\")",
+ "javascript": "g.addV().property(\"notGenerated\", \"true\").addV().property(\"notGenerated\", \"true\")",
+ "python": "g.add_v().property('notGenerated', 'true').add_v().property('notGenerated', 'true')"
+ },
+ {
+ "original": "g.V().repeat(__.addV().property(\"generated\", \"true\")).times(2)",
+ "language": "g.V().repeat(__.addV().property(\"generated\", \"true\")).times(2)",
+ "anonymized": "g.V().repeat(__.addV().property(string0, string1)).times(number0)",
+ "dotnet": "g.V().Repeat(__.AddV().Property(\"generated\", \"true\")).Times(2)",
+ "go": "g.V().Repeat(gremlingo.T__.AddV().Property(\"generated\", \"true\")).Times(2)",
+ "groovy": "g.V().repeat(__.addV().property(\"generated\", \"true\")).times(2)",
+ "java": "g.V().repeat(__.addV().property(\"generated\", \"true\")).times(2)",
+ "javascript": "g.V().repeat(__.addV().property(\"generated\", \"true\")).times(2)",
+ "python": "g.V().repeat(__.add_v().property('generated', 'true')).times(2)"
+ },
+ {
+ "original": "g.V().has(\"notGenerated\")",
+ "language": "g.V().has(\"notGenerated\")",
+ "anonymized": "g.V().has(string0)",
+ "dotnet": "g.V().Has(\"notGenerated\")",
+ "go": "g.V().Has(\"notGenerated\")",
+ "groovy": "g.V().has(\"notGenerated\")",
+ "java": "g.V().has(\"notGenerated\")",
+ "javascript": "g.V().has(\"notGenerated\")",
+ "python": "g.V().has('notGenerated')"
+ },
+ {
+ "original": "g.V().has(\"generated\")",
+ "language": "g.V().has(\"generated\")",
+ "anonymized": "g.V().has(string0)",
+ "dotnet": "g.V().Has(\"generated\")",
+ "go": "g.V().Has(\"generated\")",
+ "groovy": "g.V().has(\"generated\")",
+ "java": "g.V().has(\"generated\")",
+ "javascript": "g.V().has(\"generated\")",
+ "python": "g.V().has('generated')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXdedup_bothX_timesX2X",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.dedup().both()).times(2)",
+ "language": "g.V().repeat(__.dedup().both()).times(2)",
+ "anonymized": "g.V().repeat(__.dedup().both()).times(number0)",
+ "dotnet": "g.V().Repeat(__.Dedup().Both()).Times(2)",
+ "go": "g.V().Repeat(gremlingo.T__.Dedup().Both()).Times(2)",
+ "groovy": "g.V().repeat(__.dedup().both()).times(2)",
+ "java": "g.V().repeat(__.dedup().both()).times(2)",
+ "javascript": "g.V().repeat(__.dedup().both()).times(2)",
+ "python": "g.V().repeat(__.dedup().both()).times(2)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXaggregateXxXX_timesX2X_selectXxX_limitX1X_unfold",
+ "traversals": [
+ {
+ "original": "g.V().repeat(__.aggregate(\"x\")).times(2).select(\"x\").limit(1).unfold()",
+ "language": "g.V().repeat(__.aggregate(\"x\")).times(2).select(\"x\").limit(1).unfold()",
+ "anonymized": "g.V().repeat(__.aggregate(string0)).times(number0).select(string0).limit(number1).unfold()",
+ "dotnet": "g.V().Repeat(__.Aggregate(\"x\")).Times(2).Select<object>(\"x\").Limit<object>(1).Unfold<object>()",
+ "go": "g.V().Repeat(gremlingo.T__.Aggregate(\"x\")).Times(2).Select(\"x\").Limit(1).Unfold()",
+ "groovy": "g.V().repeat(__.aggregate(\"x\")).times(2).select(\"x\").limit(1).unfold()",
+ "java": "g.V().repeat(__.aggregate(\"x\")).times(2).select(\"x\").limit(1).unfold()",
+ "javascript": "g.V().repeat(__.aggregate(\"x\")).times(2).select(\"x\").limit(1).unfold()",
+ "python": "g.V().repeat(__.aggregate('x')).times(2).select('x').limit(1).unfold()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXstrX_repeatXsplitXabcX_conjoinX_timesX2X",
+ "traversals": [
+ {
+ "original": "g.addV().property(\"str\", \"ababcczababcc\").addV().property(\"str\", \"abcyabc\")",
+ "language": "g.addV().property(\"str\", \"ababcczababcc\").addV().property(\"str\", \"abcyabc\")",
+ "anonymized": "g.addV().property(string0, string1).addV().property(string0, string2)",
+ "dotnet": "g.AddV().Property(\"str\", \"ababcczababcc\").AddV().Property(\"str\", \"abcyabc\")",
+ "go": "g.AddV().Property(\"str\", \"ababcczababcc\").AddV().Property(\"str\", \"abcyabc\")",
+ "groovy": "g.addV().property(\"str\", \"ababcczababcc\").addV().property(\"str\", \"abcyabc\")",
+ "java": "g.addV().property(\"str\", \"ababcczababcc\").addV().property(\"str\", \"abcyabc\")",
+ "javascript": "g.addV().property(\"str\", \"ababcczababcc\").addV().property(\"str\", \"abcyabc\")",
+ "python": "g.add_v().property('str', 'ababcczababcc').add_v().property('str', 'abcyabc')"
+ },
+ {
+ "original": "g.V().values(\"str\").repeat(__.split(\"abc\").conjoin(\"\")).times(2)",
+ "language": "g.V().values(\"str\").repeat(__.split(\"abc\").conjoin(\"\")).times(2)",
+ "anonymized": "g.V().values(string0).repeat(__.split(string1).conjoin(string2)).times(number0)",
+ "dotnet": "g.V().Values<object>(\"str\").Repeat(__.Split(\"abc\").Conjoin((string) \"\")).Times(2)",
+ "go": "g.V().Values(\"str\").Repeat(gremlingo.T__.Split(\"abc\").Conjoin(\"\")).Times(2)",
+ "groovy": "g.V().values(\"str\").repeat(__.split(\"abc\").conjoin(\"\")).times(2)",
+ "java": "g.V().values(\"str\").repeat(__.split(\"abc\").conjoin(\"\")).times(2)",
+ "javascript": "g.V().values(\"str\").repeat(__.split(\"abc\").conjoin(\"\")).times(2)",
+ "python": "g.V().values('str').repeat(__.split('abc').conjoin('')).times(2)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_withSackX0X_V_repeatXsackXsumX_byXageX_whereXsack_isXltX59XXXX_timesX2X",
+ "traversals": [
+ {
+ "original": "g.withSack(0L).V().repeat(__.sack(Operator.sum).by(\"age\").where(__.sack().is(P.lt(59)))).times(2)",
+ "language": "g.withSack(0l).V().repeat(__.sack(Operator.sum).by(\"age\").where(__.sack().is(P.lt(59)))).times(2)",
+ "anonymized": "g.withSack(long0).V().repeat(__.sack(Operator.sum).by(string0).where(__.sack().is(P.lt(number0)))).times(number1)",
+ "dotnet": "g.WithSack(0l).V().Repeat(__.Sack(Operator.Sum).By(\"age\").Where(__.Sack<object>().Is(P.Lt(59)))).Times(2)",
+ "go": "g.WithSack(int64(0)).V().Repeat(gremlingo.T__.Sack(gremlingo.Operator.Sum).By(\"age\").Where(gremlingo.T__.Sack().Is(gremlingo.P.Lt(59)))).Times(2)",
+ "groovy": "g.withSack(0l).V().repeat(__.sack(Operator.sum).by(\"age\").where(__.sack().is(P.lt(59)))).times(2)",
+ "java": "g.withSack(0l).V().repeat(__.sack(Operator.sum).by(\"age\").where(__.sack().is(P.lt(59)))).times(2)",
+ "javascript": "g.withSack(0).V().repeat(__.sack(Operator.sum).by(\"age\").where(__.sack().is(P.lt(59)))).times(2)",
+ "python": "g.with_sack(long(0)).V().repeat(__.sack(Operator.sum_).by('age').where(__.sack().is_(P.lt(59)))).times(2)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXinjectXyXX_timesX2X",
+ "traversals": [
+ {
+ "original": "g.V().repeat(inject('y')).times(2)",
+ "language": "g.V().repeat(__.inject('y')).times(2)",
+ "anonymized": "g.V().repeat(__.inject(string0)).times(number0)",
+ "dotnet": "g.V().Repeat(__.Inject(\"y\")).Times(2)",
+ "go": "g.V().Repeat(gremlingo.T__.Inject(\"y\")).Times(2)",
+ "groovy": "g.V().repeat(__.inject('y')).times(2)",
+ "java": "g.V().repeat(__.inject(\"y\")).times(2)",
+ "javascript": "g.V().repeat(__.inject(\"y\")).times(2)",
+ "python": "g.V().repeat(__.inject('y')).times(2)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_repeatXunionXconstantXyX_limitX1X_identityXX_timesX3X",
+ "traversals": [
+ {
+ "original": "g.V().repeat(union(constant('y').limit(1),identity())).times(2)",
+ "language": "g.V().repeat(__.union(__.constant('y').limit(1), __.identity())).times(2)",
+ "anonymized": "g.V().repeat(__.union(__.constant(string0).limit(number0), __.identity())).times(number1)",
+ "dotnet": "g.V().Repeat(__.Union<object>(__.Constant<object>(\"y\").Limit<object>(1), __.Identity())).Times(2)",
+ "go": "g.V().Repeat(gremlingo.T__.Union(gremlingo.T__.Constant(\"y\").Limit(1), gremlingo.T__.Identity())).Times(2)",
+ "groovy": "g.V().repeat(__.union(__.constant('y').limit(1), __.identity())).times(2)",
+ "java": "g.V().repeat(__.union(__.constant(\"y\").limit(1), __.identity())).times(2)",
+ "javascript": "g.V().repeat(__.union(__.constant(\"y\").limit(1), __.identity())).times(2)",
+ "python": "g.V().repeat(__.union(__.constant('y').limit(1), __.identity())).times(2)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX3X_repeatXout_order_byXperformancesX_tailX2XX_timesX1X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(1).values(\"name\")",
+ "language": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(1).values(\"name\")",
+ "anonymized": "g.V(vid3).repeat(__.out().order().by(string0).tail(number0)).times(number1).values(string1)",
+ "dotnet": "g.V(vid3).Repeat(__.Out().Order().By(\"performances\").Tail<object>(2)).Times(1).Values<object>(\"name\")",
+ "go": "g.V(vid3).Repeat(gremlingo.T__.Out().Order().By(\"performances\").Tail(2)).Times(1).Values(\"name\")",
+ "groovy": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(1).values(\"name\")",
+ "java": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(1).values(\"name\")",
+ "javascript": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(1).values(\"name\")",
+ "python": "g.V(vid3).repeat(__.out().order().by('performances').tail(2)).times(1).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX3X_repeatXout_order_byXperformancesX_tailX2XX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(2).values(\"name\")",
+ "language": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(2).values(\"name\")",
+ "anonymized": "g.V(vid3).repeat(__.out().order().by(string0).tail(number0)).times(number0).values(string1)",
+ "dotnet": "g.V(vid3).Repeat(__.Out().Order().By(\"performances\").Tail<object>(2)).Times(2).Values<object>(\"name\")",
+ "go": "g.V(vid3).Repeat(gremlingo.T__.Out().Order().By(\"performances\").Tail(2)).Times(2).Values(\"name\")",
+ "groovy": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(2).values(\"name\")",
+ "java": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(2).values(\"name\")",
+ "javascript": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(2)).times(2).values(\"name\")",
+ "python": "g.V(vid3).repeat(__.out().order().by('performances').tail(2)).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX2X_repeatXout_localXorder_byXperformancesX_tailX1XXX_timesX1X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid2).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(1).values(\"name\")",
+ "language": "g.V(vid2).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(1).values(\"name\")",
+ "anonymized": "g.V(vid2).repeat(__.out().local(__.order().by(string0).tail(number0))).times(number0).values(string1)",
+ "dotnet": "g.V(vid2).Repeat(__.Out().Local<object>(__.Order().By(\"performances\").Tail<object>(1))).Times(1).Values<object>(\"name\")",
+ "go": "g.V(vid2).Repeat(gremlingo.T__.Out().Local(gremlingo.T__.Order().By(\"performances\").Tail(1))).Times(1).Values(\"name\")",
+ "groovy": "g.V(vid2).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(1).values(\"name\")",
+ "java": "g.V(vid2).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(1).values(\"name\")",
+ "javascript": "g.V(vid2).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(1).values(\"name\")",
+ "python": "g.V(vid2).repeat(__.out().local(__.order().by('performances').tail(1))).times(1).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX250X_repeatXout_localXorder_byXperformancesX_tailX1XXX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid250).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(2).values(\"name\")",
+ "language": "g.V(vid250).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(2).values(\"name\")",
+ "anonymized": "g.V(vid250).repeat(__.out().local(__.order().by(string0).tail(number0))).times(number1).values(string1)",
+ "dotnet": "g.V(vid250).Repeat(__.Out().Local<object>(__.Order().By(\"performances\").Tail<object>(1))).Times(2).Values<object>(\"name\")",
+ "go": "g.V(vid250).Repeat(gremlingo.T__.Out().Local(gremlingo.T__.Order().By(\"performances\").Tail(1))).Times(2).Values(\"name\")",
+ "groovy": "g.V(vid250).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(2).values(\"name\")",
+ "java": "g.V(vid250).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(2).values(\"name\")",
+ "javascript": "g.V(vid250).repeat(__.out().local(__.order().by(\"performances\").tail(1))).times(2).values(\"name\")",
+ "python": "g.V(vid250).repeat(__.out().local(__.order().by('performances').tail(1))).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX3X_repeatXout_order_byXperformancesX_tailX3X_limitX1XX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(3).limit(1)).times(2).values(\"name\")",
+ "language": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(3).limit(1)).times(2).values(\"name\")",
+ "anonymized": "g.V(vid3).repeat(__.out().order().by(string0).tail(number0).limit(number1)).times(number2).values(string1)",
+ "dotnet": "g.V(vid3).Repeat(__.Out().Order().By(\"performances\").Tail<object>(3).Limit<object>(1)).Times(2).Values<object>(\"name\")",
+ "go": "g.V(vid3).Repeat(gremlingo.T__.Out().Order().By(\"performances\").Tail(3).Limit(1)).Times(2).Values(\"name\")",
+ "groovy": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(3).limit(1)).times(2).values(\"name\")",
+ "java": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(3).limit(1)).times(2).values(\"name\")",
+ "javascript": "g.V(vid3).repeat(__.out().order().by(\"performances\").tail(3).limit(1)).times(2).values(\"name\")",
+ "python": "g.V(vid3).repeat(__.out().order().by('performances').tail(3).limit(1)).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX3X_repeatXout_order_byXperformances_descX_limitX5X_tailX1XX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid3).repeat(__.out().order().by(\"performances\", Order.desc).limit(5).tail(1)).times(2).values(\"name\")",
+ "language": "g.V(vid3).repeat(__.out().order().by(\"performances\", Order.desc).limit(5).tail(1)).times(2).values(\"name\")",
+ "anonymized": "g.V(vid3).repeat(__.out().order().by(string0, Order.desc).limit(number0).tail(number1)).times(number2).values(string1)",
+ "dotnet": "g.V(vid3).Repeat(__.Out().Order().By(\"performances\", Order.Desc).Limit<object>(5).Tail<object>(1)).Times(2).Values<object>(\"name\")",
+ "go": "g.V(vid3).Repeat(gremlingo.T__.Out().Order().By(\"performances\", gremlingo.Order.Desc).Limit(5).Tail(1)).Times(2).Values(\"name\")",
+ "groovy": "g.V(vid3).repeat(__.out().order().by(\"performances\", Order.desc).limit(5).tail(1)).times(2).values(\"name\")",
+ "java": "g.V(vid3).repeat(__.out().order().by(\"performances\", Order.desc).limit(5).tail(1)).times(2).values(\"name\")",
+ "javascript": "g.V(vid3).repeat(__.out().order().by(\"performances\", Order.desc).limit(5).tail(1)).times(2).values(\"name\")",
+ "python": "g.V(vid3).repeat(__.out().order().by('performances', Order.desc).limit(5).tail(1)).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX3X_repeatXoutE_order_byXweightX_tailX2X_inVX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid3).repeat(__.outE().order().by(\"weight\").tail(2).inV()).times(2).values(\"name\")",
+ "language": "g.V(vid3).repeat(__.outE().order().by(\"weight\").tail(2).inV()).times(2).values(\"name\")",
+ "anonymized": "g.V(vid3).repeat(__.outE().order().by(string0).tail(number0).inV()).times(number0).values(string1)",
+ "dotnet": "g.V(vid3).Repeat(__.OutE().Order().By(\"weight\").Tail<object>(2).InV()).Times(2).Values<object>(\"name\")",
+ "go": "g.V(vid3).Repeat(gremlingo.T__.OutE().Order().By(\"weight\").Tail(2).InV()).Times(2).Values(\"name\")",
+ "groovy": "g.V(vid3).repeat(__.outE().order().by(\"weight\").tail(2).inV()).times(2).values(\"name\")",
+ "java": "g.V(vid3).repeat(__.outE().order().by(\"weight\").tail(2).inV()).times(2).values(\"name\")",
+ "javascript": "g.V(vid3).repeat(__.outE().order().by(\"weight\").tail(2).inV()).times(2).values(\"name\")",
+ "python": "g.V(vid3).repeat(__.out_e().order().by('weight').tail(2).in_v()).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX3X_repeatXoutE_order_byXweight_descX_limitX2X_inVX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V(vid3).repeat(__.outE().order().by(\"weight\", Order.desc).limit(2).inV()).times(2).values(\"name\")",
+ "language": "g.V(vid3).repeat(__.outE().order().by(\"weight\", Order.desc).limit(2).inV()).times(2).values(\"name\")",
+ "anonymized": "g.V(vid3).repeat(__.outE().order().by(string0, Order.desc).limit(number0).inV()).times(number0).values(string1)",
+ "dotnet": "g.V(vid3).Repeat(__.OutE().Order().By(\"weight\", Order.Desc).Limit<object>(2).InV()).Times(2).Values<object>(\"name\")",
+ "go": "g.V(vid3).Repeat(gremlingo.T__.OutE().Order().By(\"weight\", gremlingo.Order.Desc).Limit(2).InV()).Times(2).Values(\"name\")",
+ "groovy": "g.V(vid3).repeat(__.outE().order().by(\"weight\", Order.desc).limit(2).inV()).times(2).values(\"name\")",
+ "java": "g.V(vid3).repeat(__.outE().order().by(\"weight\", Order.desc).limit(2).inV()).times(2).values(\"name\")",
+ "javascript": "g.V(vid3).repeat(__.outE().order().by(\"weight\", Order.desc).limit(2).inV()).times(2).values(\"name\")",
+ "python": "g.V(vid3).repeat(__.out_e().order().by('weight', Order.desc).limit(2).in_v()).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit_repeatXout_order_byXnameXX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V().emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "language": "g.V().emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "anonymized": "g.V().emit().repeat(__.out().order().by(string0)).times(number0).values(string0)",
+ "dotnet": "g.V().Emit().Repeat(__.Out().Order().By(\"name\")).Times(2).Values<object>(\"name\")",
+ "go": "g.V().Emit().Repeat(gremlingo.T__.Out().Order().By(\"name\")).Times(2).Values(\"name\")",
+ "groovy": "g.V().emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "java": "g.V().emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "javascript": "g.V().emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "python": "g.V().emit().repeat(__.out().order().by('name')).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXemit_repeatXout_order_byXnameXX_timesX2X_valuesXnameXX",
+ "traversals": [
+ {
+ "original": "g.V().local(__.emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\"))",
+ "language": "g.V().local(__.emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\"))",
+ "anonymized": "g.V().local(__.emit().repeat(__.out().order().by(string0)).times(number0).values(string0))",
+ "dotnet": "g.V().Local<object>(__.Emit().Repeat(__.Out().Order().By(\"name\")).Times(2).Values<object>(\"name\"))",
+ "go": "g.V().Local(gremlingo.T__.Emit().Repeat(gremlingo.T__.Out().Order().By(\"name\")).Times(2).Values(\"name\"))",
+ "groovy": "g.V().local(__.emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\"))",
+ "java": "g.V().local(__.emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\"))",
+ "javascript": "g.V().local(__.emit().repeat(__.out().order().by(\"name\")).times(2).values(\"name\"))",
+ "python": "g.V().local(__.emit().repeat(__.out().order().by('name')).times(2).values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit_repeatXlocalXout_order_byXnameXXX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V().emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\")",
+ "language": "g.V().emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\")",
+ "anonymized": "g.V().emit().repeat(__.local(__.out().order().by(string0))).times(number0).values(string0)",
+ "dotnet": "g.V().Emit().Repeat(__.Local<object>(__.Out().Order().By(\"name\"))).Times(2).Values<object>(\"name\")",
+ "go": "g.V().Emit().Repeat(gremlingo.T__.Local(gremlingo.T__.Out().Order().By(\"name\"))).Times(2).Values(\"name\")",
+ "groovy": "g.V().emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\")",
+ "java": "g.V().emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\")",
+ "javascript": "g.V().emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\")",
+ "python": "g.V().emit().repeat(__.local(__.out().order().by('name'))).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_localXemit_repeatXlocalXout_order_byXnameXXX_timesX2X_valuesXnameXX",
+ "traversals": [
+ {
+ "original": "g.V().local(__.emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\"))",
+ "language": "g.V().local(__.emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\"))",
+ "anonymized": "g.V().local(__.emit().repeat(__.local(__.out().order().by(string0))).times(number0).values(string0))",
+ "dotnet": "g.V().Local<object>(__.Emit().Repeat(__.Local<object>(__.Out().Order().By(\"name\"))).Times(2).Values<object>(\"name\"))",
+ "go": "g.V().Local(gremlingo.T__.Emit().Repeat(gremlingo.T__.Local(gremlingo.T__.Out().Order().By(\"name\"))).Times(2).Values(\"name\"))",
+ "groovy": "g.V().local(__.emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\"))",
+ "java": "g.V().local(__.emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\"))",
+ "javascript": "g.V().local(__.emit().repeat(__.local(__.out().order().by(\"name\"))).times(2).values(\"name\"))",
+ "python": "g.V().local(__.emit().repeat(__.local(__.out().order().by('name'))).times(2).values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emitXhasLabelXpersonXX_repeatXout_order_byXnameXX_timesX2X_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V().emit(__.hasLabel(\"person\")).repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "language": "g.V().emit(__.hasLabel(\"person\")).repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "anonymized": "g.V().emit(__.hasLabel(string0)).repeat(__.out().order().by(string1)).times(number0).values(string1)",
+ "dotnet": "g.V().Emit(__.HasLabel(\"person\")).Repeat(__.Out().Order().By(\"name\")).Times(2).Values<object>(\"name\")",
+ "go": "g.V().Emit(gremlingo.T__.HasLabel(\"person\")).Repeat(gremlingo.T__.Out().Order().By(\"name\")).Times(2).Values(\"name\")",
+ "groovy": "g.V().emit(__.hasLabel(\"person\")).repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "java": "g.V().emit(__.hasLabel(\"person\")).repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "javascript": "g.V().emit(__.hasLabel(\"person\")).repeat(__.out().order().by(\"name\")).times(2).values(\"name\")",
+ "python": "g.V().emit(__.has_label('person')).repeat(__.out().order().by('name')).times(2).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_untilXloops_isX2XX_repeatXout_order_byXnameXX_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V().until(__.loops().is(2)).repeat(__.out().order().by(\"name\")).values(\"name\")",
+ "language": "g.V().until(__.loops().is(2)).repeat(__.out().order().by(\"name\")).values(\"name\")",
+ "anonymized": "g.V().until(__.loops().is(number0)).repeat(__.out().order().by(string0)).values(string0)",
+ "dotnet": "g.V().Until(__.Loops().Is(2)).Repeat(__.Out().Order().By(\"name\")).Values<object>(\"name\")",
+ "go": "g.V().Until(gremlingo.T__.Loops().Is(2)).Repeat(gremlingo.T__.Out().Order().By(\"name\")).Values(\"name\")",
+ "groovy": "g.V().until(__.loops().is(2)).repeat(__.out().order().by(\"name\")).values(\"name\")",
+ "java": "g.V().until(__.loops().is(2)).repeat(__.out().order().by(\"name\")).values(\"name\")",
+ "javascript": "g.V().until(__.loops().is(2)).repeat(__.out().order().by(\"name\")).values(\"name\")",
+ "python": "g.V().until(__.loops().is_(2)).repeat(__.out().order().by('name')).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit_repeatXdedupX_timesX1X",
+ "traversals": [
+ {
+ "original": "g.V().emit().repeat(__.dedup()).times(1)",
+ "language": "g.V().emit().repeat(__.dedup()).times(1)",
+ "anonymized": "g.V().emit().repeat(__.dedup()).times(number0)",
+ "dotnet": "g.V().Emit().Repeat(__.Dedup()).Times(1)",
+ "go": "g.V().Emit().Repeat(gremlingo.T__.Dedup()).Times(1)",
+ "groovy": "g.V().emit().repeat(__.dedup()).times(1)",
+ "java": "g.V().emit().repeat(__.dedup()).times(1)",
+ "javascript": "g.V().emit().repeat(__.dedup()).times(1)",
+ "python": "g.V().emit().repeat(__.dedup()).times(1)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_emit_repeatXdedupX_timesX2X",
+ "traversals": [
+ {
+ "original": "g.V().emit().repeat(__.dedup()).times(2)",
+ "language": "g.V().emit().repeat(__.dedup()).times(2)",
+ "anonymized": "g.V().emit().repeat(__.dedup()).times(number0)",
+ "dotnet": "g.V().Emit().Repeat(__.Dedup()).Times(2)",
+ "go": "g.V().Emit().Repeat(gremlingo.T__.Dedup()).Times(2)",
+ "groovy": "g.V().emit().repeat(__.dedup()).times(2)",
+ "java": "g.V().emit().repeat(__.dedup()).times(2)",
+ "javascript": "g.V().emit().repeat(__.dedup()).times(2)",
+ "python": "g.V().emit().repeat(__.dedup()).times(2)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXX",
+ "traversals": [
+ {
+ "original": "g.union()",
+ "language": "g.union()",
+ "anonymized": "g.union()",
+ "dotnet": "g.Union<object>()",
+ "go": "g.Union()",
+ "groovy": "g.union()",
+ "java": "g.union()",
+ "javascript": "g.union()",
+ "python": "g.union()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXV_name",
+ "traversals": [
+ {
+ "original": "g.union(__.V().values(\"name\"))",
+ "language": "g.union(__.V().values(\"name\"))",
+ "anonymized": "g.union(__.V().values(string0))",
+ "dotnet": "g.Union<object>(__.V().Values<object>(\"name\"))",
+ "go": "g.Union(gremlingo.T__.V().Values(\"name\"))",
+ "groovy": "g.union(__.V().values(\"name\"))",
+ "java": "g.union(__.V().values(\"name\"))",
+ "javascript": "g.union(__.V().values(\"name\"))",
+ "python": "g.union(__.V().values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXVXv1X_VX4XX_name",
+ "traversals": [
+ {
+ "original": "g.union(__.V(vid1), __.V(vid4)).values(\"name\")",
+ "language": "g.union(__.V(vid1), __.V(vid4)).values(\"name\")",
+ "anonymized": "g.union(__.V(vid1), __.V(vid4)).values(string0)",
+ "dotnet": "g.Union<object>(__.V(vid1), __.V(vid4)).Values<object>(\"name\")",
+ "go": "g.Union(gremlingo.T__.V(vid1), gremlingo.T__.V(vid4)).Values(\"name\")",
+ "groovy": "g.union(__.V(vid1), __.V(vid4)).values(\"name\")",
+ "java": "g.union(__.V(vid1), __.V(vid4)).values(\"name\")",
+ "javascript": "g.union(__.V(vid1), __.V(vid4)).values(\"name\")",
+ "python": "g.union(__.V(vid1), __.V(vid4)).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXV_hasLabelXsoftwareX_V_hasLabelXpersonXX_name",
+ "traversals": [
+ {
+ "original": "g.union(__.V().hasLabel(\"software\"), __.V().hasLabel(\"person\")).values(\"name\")",
+ "language": "g.union(__.V().hasLabel(\"software\"), __.V().hasLabel(\"person\")).values(\"name\")",
+ "anonymized": "g.union(__.V().hasLabel(string0), __.V().hasLabel(string1)).values(string2)",
+ "dotnet": "g.Union<object>(__.V().HasLabel(\"software\"), __.V().HasLabel(\"person\")).Values<object>(\"name\")",
+ "go": "g.Union(gremlingo.T__.V().HasLabel(\"software\"), gremlingo.T__.V().HasLabel(\"person\")).Values(\"name\")",
+ "groovy": "g.union(__.V().hasLabel(\"software\"), __.V().hasLabel(\"person\")).values(\"name\")",
+ "java": "g.union(__.V().hasLabel(\"software\"), __.V().hasLabel(\"person\")).values(\"name\")",
+ "javascript": "g.union(__.V().hasLabel(\"software\"), __.V().hasLabel(\"person\")).values(\"name\")",
+ "python": "g.union(__.V().has_label('software'), __.V().has_label('person')).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXV_out_out_V_hasLabelXsoftwareXX_path",
+ "traversals": [
+ {
+ "original": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path()",
+ "language": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path()",
+ "anonymized": "g.union(__.V().out().out(), __.V().hasLabel(string0)).path()",
+ "dotnet": "g.Union<object>(__.V().Out().Out(), __.V().HasLabel(\"software\")).Path()",
+ "go": "g.Union(gremlingo.T__.V().Out().Out(), gremlingo.T__.V().HasLabel(\"software\")).Path()",
+ "groovy": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path()",
+ "java": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path()",
+ "javascript": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path()",
+ "python": "g.union(__.V().out().out(), __.V().has_label('software')).path()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXV_out_out_V_hasLabelXsoftwareXX_path_byXnameX",
+ "traversals": [
+ {
+ "original": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "language": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "anonymized": "g.union(__.V().out().out(), __.V().hasLabel(string0)).path().by(string1)",
+ "dotnet": "g.Union<object>(__.V().Out().Out(), __.V().HasLabel(\"software\")).Path().By(\"name\")",
+ "go": "g.Union(gremlingo.T__.V().Out().Out(), gremlingo.T__.V().HasLabel(\"software\")).Path().By(\"name\")",
+ "groovy": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "java": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "javascript": "g.union(__.V().out().out(), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "python": "g.union(__.V().out().out(), __.V().has_label('software')).path().by('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXunionXV_out_outX_V_hasLabelXsoftwareXX_path_byXnameX",
+ "traversals": [
+ {
+ "original": "g.union(__.union(__.V().out().out()), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "language": "g.union(__.union(__.V().out().out()), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "anonymized": "g.union(__.union(__.V().out().out()), __.V().hasLabel(string0)).path().by(string1)",
+ "dotnet": "g.Union<object>(__.Union<object>(__.V().Out().Out()), __.V().HasLabel(\"software\")).Path().By(\"name\")",
+ "go": "g.Union(gremlingo.T__.Union(gremlingo.T__.V().Out().Out()), gremlingo.T__.V().HasLabel(\"software\")).Path().By(\"name\")",
+ "groovy": "g.union(__.union(__.V().out().out()), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "java": "g.union(__.union(__.V().out().out()), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "javascript": "g.union(__.union(__.V().out().out()), __.V().hasLabel(\"software\")).path().by(\"name\")",
+ "python": "g.union(__.union(__.V().out().out()), __.V().has_label('software')).path().by('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXinjectX1X_injectX2X",
+ "traversals": [
+ {
+ "original": "g.union(__.inject(1), __.inject(2))",
+ "language": "g.union(__.inject(1), __.inject(2))",
+ "anonymized": "g.union(__.inject(number0), __.inject(number1))",
+ "dotnet": "g.Union<object>(__.Inject(1), __.Inject(2))",
+ "go": "g.Union(gremlingo.T__.Inject(1), gremlingo.T__.Inject(2))",
+ "groovy": "g.union(__.inject(1), __.inject(2))",
+ "java": "g.union(__.inject(1), __.inject(2))",
+ "javascript": "g.union(__.inject(1), __.inject(2))",
+ "python": "g.union(__.inject(1), __.inject(2))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_unionXconstantX1X_constantX2X_constantX3XX",
+ "traversals": [
+ {
+ "original": "g.V(vid2).union(constant(1i), constant(2i), constant(3i))",
+ "language": "g.V(vid2).union(__.constant(1i), __.constant(2i), __.constant(3i))",
+ "anonymized": "g.V(vid2).union(__.constant(integer0), __.constant(integer1), __.constant(integer2))",
+ "dotnet": "g.V(vid2).Union<object>(__.Constant<object>(1), __.Constant<object>(2), __.Constant<object>(3))",
+ "go": "g.V(vid2).Union(gremlingo.T__.Constant(int32(1)), gremlingo.T__.Constant(int32(2)), gremlingo.T__.Constant(int32(3)))",
+ "groovy": "g.V(vid2).union(__.constant(1i), __.constant(2i), __.constant(3i))",
+ "java": "g.V(vid2).union(__.constant(1), __.constant(2), __.constant(3))",
+ "javascript": "g.V(vid2).union(__.constant(1), __.constant(2), __.constant(3))",
+ "python": "g.V(vid2).union(__.constant(1), __.constant(2), __.constant(3))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_unionXout__inX_name",
+ "traversals": [
+ {
+ "original": "g.V().union(__.out(), __.in()).values(\"name\")",
+ "language": "g.V().union(__.out(), __.in()).values(\"name\")",
+ "anonymized": "g.V().union(__.out(), __.in()).values(string0)",
+ "dotnet": "g.V().Union<object>(__.Out(), __.In()).Values<object>(\"name\")",
+ "go": "g.V().Union(gremlingo.T__.Out(), gremlingo.T__.In()).Values(\"name\")",
+ "groovy": "g.V().union(__.out(), __.in()).values(\"name\")",
+ "java": "g.V().union(__.out(), __.in()).values(\"name\")",
+ "javascript": "g.V().union(__.out(), __.in_()).values(\"name\")",
+ "python": "g.V().union(__.out(), __.in_()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1X_unionXrepeatXoutX_timesX2X__outX_name",
+ "traversals": [
+ {
+ "original": "g.V(vid1).union(__.repeat(__.out()).times(2), __.out()).values(\"name\")",
+ "language": "g.V(vid1).union(__.repeat(__.out()).times(2), __.out()).values(\"name\")",
+ "anonymized": "g.V(vid1).union(__.repeat(__.out()).times(number0), __.out()).values(string0)",
+ "dotnet": "g.V(vid1).Union<object>(__.Repeat(__.Out()).Times(2), __.Out()).Values<object>(\"name\")",
+ "go": "g.V(vid1).Union(gremlingo.T__.Repeat(gremlingo.T__.Out()).Times(2), gremlingo.T__.Out()).Values(\"name\")",
+ "groovy": "g.V(vid1).union(__.repeat(__.out()).times(2), __.out()).values(\"name\")",
+ "java": "g.V(vid1).union(__.repeat(__.out()).times(2), __.out()).values(\"name\")",
+ "javascript": "g.V(vid1).union(__.repeat(__.out()).times(2), __.out()).values(\"name\")",
+ "python": "g.V(vid1).union(__.repeat(__.out()).times(2), __.out()).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXlabel_is_person__unionX__out_lang__out_nameX__in_labelX",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label())",
+ "language": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label())",
+ "anonymized": "g.V().choose(__.label().is(string0), __.union(__.out().values(string1), __.out().values(string2)), __.in().label())",
+ "dotnet": "g.V().Choose<object>(__.Label().Is(\"person\"), __.Union<object>(__.Out().Values<object>(\"lang\"), __.Out().Values<object>(\"name\")), __.In().Label())",
+ "go": "g.V().Choose(gremlingo.T__.Label().Is(\"person\"), gremlingo.T__.Union(gremlingo.T__.Out().Values(\"lang\"), gremlingo.T__.Out().Values(\"name\")), gremlingo.T__.In().Label())",
+ "groovy": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label())",
+ "java": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label())",
+ "javascript": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in_().label())",
+ "python": "g.V().choose(__.label().is_('person'), __.union(__.out().values('lang'), __.out().values('name')), __.in_().label())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_chooseXlabel_is_person__unionX__out_lang__out_nameX__in_labelX_groupCount",
+ "traversals": [
+ {
+ "original": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label()).groupCount()",
+ "language": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label()).groupCount()",
+ "anonymized": "g.V().choose(__.label().is(string0), __.union(__.out().values(string1), __.out().values(string2)), __.in().label()).groupCount()",
+ "dotnet": "g.V().Choose<object>(__.Label().Is(\"person\"), __.Union<object>(__.Out().Values<object>(\"lang\"), __.Out().Values<object>(\"name\")), __.In().Label()).GroupCount<object>()",
+ "go": "g.V().Choose(gremlingo.T__.Label().Is(\"person\"), gremlingo.T__.Union(gremlingo.T__.Out().Values(\"lang\"), gremlingo.T__.Out().Values(\"name\")), gremlingo.T__.In().Label()).GroupCount()",
+ "groovy": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label()).groupCount()",
+ "java": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in().label()).groupCount()",
+ "javascript": "g.V().choose(__.label().is(\"person\"), __.union(__.out().values(\"lang\"), __.out().values(\"name\")), __.in_().label()).groupCount()",
+ "python": "g.V().choose(__.label().is_('person'), __.union(__.out().values('lang'), __.out().values('name')), __.in_().label()).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_unionXrepeatXunionXoutXcreatedX__inXcreatedXX_timesX2X__repeatXunionXinXcreatedX__outXcreatedXX_timesX2XX_label_groupCount",
+ "traversals": [
+ {
+ "original": "g.V().union(__.repeat(__.union(__.out(\"created\"),__.in(\"created\"))).times(2),__.repeat(__.union(__.in(\"created\"),__.out(\"created\"))).times(2)).label().groupCount()",
+ "language": "g.V().union(__.repeat(__.union(__.out(\"created\"), __.in(\"created\"))).times(2), __.repeat(__.union(__.in(\"created\"), __.out(\"created\"))).times(2)).label().groupCount()",
+ "anonymized": "g.V().union(__.repeat(__.union(__.out(string0), __.in(string0))).times(number0), __.repeat(__.union(__.in(string0), __.out(string0))).times(number0)).label().groupCount()",
+ "dotnet": "g.V().Union<object>(__.Repeat(__.Union<object>(__.Out(\"created\"), __.In(\"created\"))).Times(2), __.Repeat(__.Union<object>(__.In(\"created\"), __.Out(\"created\"))).Times(2)).Label().GroupCount<object>()",
+ "go": "g.V().Union(gremlingo.T__.Repeat(gremlingo.T__.Union(gremlingo.T__.Out(\"created\"), gremlingo.T__.In(\"created\"))).Times(2), gremlingo.T__.Repeat(gremlingo.T__.Union(gremlingo.T__.In(\"created\"), gremlingo.T__.Out(\"created\"))).Times(2)).Label().GroupCount()",
+ "groovy": "g.V().union(__.repeat(__.union(__.out(\"created\"), __.in(\"created\"))).times(2), __.repeat(__.union(__.in(\"created\"), __.out(\"created\"))).times(2)).label().groupCount()",
+ "java": "g.V().union(__.repeat(__.union(__.out(\"created\"), __.in(\"created\"))).times(2), __.repeat(__.union(__.in(\"created\"), __.out(\"created\"))).times(2)).label().groupCount()",
+ "javascript": "g.V().union(__.repeat(__.union(__.out(\"created\"), __.in_(\"created\"))).times(2), __.repeat(__.union(__.in_(\"created\"), __.out(\"created\"))).times(2)).label().groupCount()",
+ "python": "g.V().union(__.repeat(__.union(__.out('created'), __.in_('created'))).times(2), __.repeat(__.union(__.in_('created'), __.out('created'))).times(2)).label().group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1_2X_unionXoutE_count__inE_count__outE_weight_sumX",
+ "traversals": [
+ {
+ "original": "g.V(vid1, vid2).union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum())",
+ "language": "g.V(vid1, vid2).union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum())",
+ "anonymized": "g.V(vid1, vid2).union(__.outE().count(), __.inE().count(), __.outE().values(string0).sum())",
+ "dotnet": "g.V(vid1, vid2).Union<object>(__.OutE().Count(), __.InE().Count(), __.OutE().Values<object>(\"weight\").Sum<object>())",
+ "go": "g.V(vid1, vid2).Union(gremlingo.T__.OutE().Count(), gremlingo.T__.InE().Count(), gremlingo.T__.OutE().Values(\"weight\").Sum())",
+ "groovy": "g.V(vid1, vid2).union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum())",
+ "java": "g.V(vid1, vid2).union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum())",
+ "javascript": "g.V(vid1, vid2).union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum())",
+ "python": "g.V(vid1, vid2).union(__.out_e().count(), __.in_e().count(), __.out_e().values('weight').sum_())"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1_2X_localXunionXoutE_count__inE_count__outE_weight_sumXX",
+ "traversals": [
+ {
+ "original": "g.V(vid1, vid2).local(__.union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum()))",
+ "language": "g.V(vid1, vid2).local(__.union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum()))",
+ "anonymized": "g.V(vid1, vid2).local(__.union(__.outE().count(), __.inE().count(), __.outE().values(string0).sum()))",
+ "dotnet": "g.V(vid1, vid2).Local<object>(__.Union<object>(__.OutE().Count(), __.InE().Count(), __.OutE().Values<object>(\"weight\").Sum<object>()))",
+ "go": "g.V(vid1, vid2).Local(gremlingo.T__.Union(gremlingo.T__.OutE().Count(), gremlingo.T__.InE().Count(), gremlingo.T__.OutE().Values(\"weight\").Sum()))",
+ "groovy": "g.V(vid1, vid2).local(__.union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum()))",
+ "java": "g.V(vid1, vid2).local(__.union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum()))",
+ "javascript": "g.V(vid1, vid2).local(__.union(__.outE().count(), __.inE().count(), __.outE().values(\"weight\").sum()))",
+ "python": "g.V(vid1, vid2).local(__.union(__.out_e().count(), __.in_e().count(), __.out_e().values('weight').sum_()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX1_2X_localXunionXcountXX",
+ "traversals": [
+ {
+ "original": "g.V(vid1, vid2).local(__.union(__.count()))",
+ "language": "g.V(vid1, vid2).local(__.union(__.count()))",
+ "anonymized": "g.V(vid1, vid2).local(__.union(__.count()))",
+ "dotnet": "g.V(vid1, vid2).Local<object>(__.Union<object>(__.Count()))",
+ "go": "g.V(vid1, vid2).Local(gremlingo.T__.Union(gremlingo.T__.Count()))",
+ "groovy": "g.V(vid1, vid2).local(__.union(__.count()))",
+ "java": "g.V(vid1, vid2).local(__.union(__.count()))",
+ "javascript": "g.V(vid1, vid2).local(__.union(__.count()))",
+ "python": "g.V(vid1, vid2).local(__.union(__.count()))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_unionXaddVXpersonX_propertyXname_aliceX_addVXpersonX_propertyXname_bobX_addVXpersonX_propertyXname_chrisX_name",
+ "traversals": [
+ {
+ "original": "g.union(__.addV(\"person\").property(\"name\", \"alice\"),__.addV(\"person\").property(\"name\", \"bob\"),__.addV(\"person\").property(\"name\", \"chris\")).values(\"name\")",
+ "language": "g.union(__.addV(\"person\").property(\"name\", \"alice\"), __.addV(\"person\").property(\"name\", \"bob\"), __.addV(\"person\").property(\"name\", \"chris\")).values(\"name\")",
+ "anonymized": "g.union(__.addV(string0).property(string1, string2), __.addV(string0).property(string1, string3), __.addV(string0).property(string1, string4)).values(string1)",
+ "dotnet": "g.Union<object>(__.AddV((string) \"person\").Property(\"name\", \"alice\"), __.AddV((string) \"person\").Property(\"name\", \"bob\"), __.AddV((string) \"person\").Property(\"name\", \"chris\")).Values<object>(\"name\")",
+ "go": "g.Union(gremlingo.T__.AddV(\"person\").Property(\"name\", \"alice\"), gremlingo.T__.AddV(\"person\").Property(\"name\", \"bob\"), gremlingo.T__.AddV(\"person\").Property(\"name\", \"chris\")).Values(\"name\")",
+ "groovy": "g.union(__.addV(\"person\").property(\"name\", \"alice\"), __.addV(\"person\").property(\"name\", \"bob\"), __.addV(\"person\").property(\"name\", \"chris\")).values(\"name\")",
+ "java": "g.union(__.addV(\"person\").property(\"name\", \"alice\"), __.addV(\"person\").property(\"name\", \"bob\"), __.addV(\"person\").property(\"name\", \"chris\")).values(\"name\")",
+ "javascript": "g.union(__.addV(\"person\").property(\"name\", \"alice\"), __.addV(\"person\").property(\"name\", \"bob\"), __.addV(\"person\").property(\"name\", \"chris\")).values(\"name\")",
+ "python": "g.union(__.add_v('person').property('name', 'alice'), __.add_v('person').property('name', 'bob'), __.add_v('person').property('name', 'chris')).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_VX_hasLabelXpersonX_unionX_whereX_out_count_isXgtX2XXX_valuesXageX_notX_whereX_bothE_count_isXgt2XXX_valusXnameXX",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").union(where(outE().count().is(P.gt(2))).values(\"age\"),__.not(where(outE().count().is(P.gt(2)))).values(\"name\"))",
+ "language": "g.V().hasLabel(\"person\").union(__.where(__.outE().count().is(P.gt(2))).values(\"age\"), __.not(__.where(__.outE().count().is(P.gt(2)))).values(\"name\"))",
+ "anonymized": "g.V().hasLabel(string0).union(__.where(__.outE().count().is(P.gt(number0))).values(string1), __.not(__.where(__.outE().count().is(P.gt(number0)))).values(string2))",
+ "dotnet": "g.V().HasLabel(\"person\").Union<object>(__.Where(__.OutE().Count().Is(P.Gt(2))).Values<object>(\"age\"), __.Not(__.Where(__.OutE().Count().Is(P.Gt(2)))).Values<object>(\"name\"))",
+ "go": "g.V().HasLabel(\"person\").Union(gremlingo.T__.Where(gremlingo.T__.OutE().Count().Is(gremlingo.P.Gt(2))).Values(\"age\"), gremlingo.T__.Not(gremlingo.T__.Where(gremlingo.T__.OutE().Count().Is(gremlingo.P.Gt(2)))).Values(\"name\"))",
+ "groovy": "g.V().hasLabel(\"person\").union(__.where(__.outE().count().is(P.gt(2))).values(\"age\"), __.not(__.where(__.outE().count().is(P.gt(2)))).values(\"name\"))",
+ "java": "g.V().hasLabel(\"person\").union(__.where(__.outE().count().is(P.gt(2))).values(\"age\"), __.not(__.where(__.outE().count().is(P.gt(2)))).values(\"name\"))",
+ "javascript": "g.V().hasLabel(\"person\").union(__.where(__.outE().count().is(P.gt(2))).values(\"age\"), __.not(__.where(__.outE().count().is(P.gt(2)))).values(\"name\"))",
+ "python": "g.V().has_label('person').union(__.where(__.out_e().count().is_(P.gt(2))).values('age'), __.not_(__.where(__.out_e().count().is_(P.gt(2)))).values('name'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 123)",
+ "language": "g.addV(\"data\").property(\"int\", 123)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 123)",
+ "go": "g.AddV(\"data\").Property(\"int\", 123)",
+ "groovy": "g.addV(\"data\").property(\"int\", 123)",
+ "java": "g.addV(\"data\").property(\"int\", 123)",
+ "javascript": "g.addV(\"data\").property(\"int\", 123)",
+ "python": "g.add_v('data').property('int', 123)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL))",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL))",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal))",
+ "python": "g.V().values('int').as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX_mathXaddX0_5XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 10)",
+ "language": "g.addV(\"data\").property(\"int\", 10)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 10)",
+ "go": "g.AddV(\"data\").Property(\"int\", 10)",
+ "groovy": "g.addV(\"data\").property(\"int\", 10)",
+ "java": "g.addV(\"data\").property(\"int\", 10)",
+ "javascript": "g.addV(\"data\").property(\"int\", 10)",
+ "python": "g.add_v('data').property('int', 10)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).math(\"_ + 0.5\")",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).math(\"_ + 0.5\")",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).math(string1)",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal)).Math(\"_ + 0.5\")",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal)).Math(\"_ + 0.5\")",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).math(\"_ + 0.5\")",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).math(\"_ + 0.5\")",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal)).math(\"_ + 0.5\")",
+ "python": "g.V().values('int').as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL)).math('_ + 0.5')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX_isXgtX0XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 5)",
+ "language": "g.addV(\"data\").property(\"int\", 5)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 5)",
+ "go": "g.AddV(\"data\").Property(\"int\", 5)",
+ "groovy": "g.addV(\"data\").property(\"int\", 5)",
+ "java": "g.addV(\"data\").property(\"int\", 5)",
+ "javascript": "g.addV(\"data\").property(\"int\", 5)",
+ "python": "g.add_v('data').property('int', 5)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).is(P.gt(0))",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).is(P.gt(0))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).is(P.gt(number0))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal)).Is(P.Gt(0))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal)).Is(gremlingo.P.Gt(0))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).is(P.gt(0))",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).is(P.gt(0))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal)).is(P.gt(0))",
+ "python": "g.V().values('int').as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL)).is_(P.gt(0))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX_sumX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3).addV(\"data\").property(\"int\", 4)",
+ "language": "g.addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3).addV(\"data\").property(\"int\", 4)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 2).AddV((string) \"data\").Property(\"int\", 3).AddV((string) \"data\").Property(\"int\", 4)",
+ "go": "g.AddV(\"data\").Property(\"int\", 2).AddV(\"data\").Property(\"int\", 3).AddV(\"data\").Property(\"int\", 4)",
+ "groovy": "g.addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3).addV(\"data\").property(\"int\", 4)",
+ "java": "g.addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3).addV(\"data\").property(\"int\", 4)",
+ "javascript": "g.addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3).addV(\"data\").property(\"int\", 4)",
+ "python": "g.add_v('data').property('int', 2).add_v('data').property('int', 3).add_v('data').property('int', 4)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).sum()",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).sum()",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).sum()",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal)).Sum<object>()",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal)).Sum()",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).sum()",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).sum()",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal)).sum()",
+ "python": "g.V().values('int').as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL)).sum_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX_minX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 10)",
+ "language": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 10)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 1).AddV((string) \"data\").Property(\"int\", 5).AddV((string) \"data\").Property(\"int\", 10)",
+ "go": "g.AddV(\"data\").Property(\"int\", 1).AddV(\"data\").Property(\"int\", 5).AddV(\"data\").Property(\"int\", 10)",
+ "groovy": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 10)",
+ "java": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 10)",
+ "javascript": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 10)",
+ "python": "g.add_v('data').property('int', 1).add_v('data').property('int', 5).add_v('data').property('int', 10)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).min()",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).min()",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).min()",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal)).Min<object>()",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal)).Min()",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).min()",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).min()",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal)).min()",
+ "python": "g.V().values('int').as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL)).min_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX_maxX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 7).addV(\"data\").property(\"int\", 14).addV(\"data\").property(\"int\", 21)",
+ "language": "g.addV(\"data\").property(\"int\", 7).addV(\"data\").property(\"int\", 14).addV(\"data\").property(\"int\", 21)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 7).AddV((string) \"data\").Property(\"int\", 14).AddV((string) \"data\").Property(\"int\", 21)",
+ "go": "g.AddV(\"data\").Property(\"int\", 7).AddV(\"data\").Property(\"int\", 14).AddV(\"data\").Property(\"int\", 21)",
+ "groovy": "g.addV(\"data\").property(\"int\", 7).addV(\"data\").property(\"int\", 14).addV(\"data\").property(\"int\", 21)",
+ "java": "g.addV(\"data\").property(\"int\", 7).addV(\"data\").property(\"int\", 14).addV(\"data\").property(\"int\", 21)",
+ "javascript": "g.addV(\"data\").property(\"int\", 7).addV(\"data\").property(\"int\", 14).addV(\"data\").property(\"int\", 21)",
+ "python": "g.add_v('data').property('int', 7).add_v('data').property('int', 14).add_v('data').property('int', 21)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).max()",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).max()",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).max()",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal)).Max<object>()",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal)).Max()",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).max()",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).max()",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal)).max()",
+ "python": "g.V().values('int').as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL)).max_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX_project_byXidentityX_byXmathXmulX10XXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 6)",
+ "language": "g.addV(\"data\").property(\"int\", 6)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 6)",
+ "go": "g.AddV(\"data\").Property(\"int\", 6)",
+ "groovy": "g.addV(\"data\").property(\"int\", 6)",
+ "java": "g.addV(\"data\").property(\"int\", 6)",
+ "javascript": "g.addV(\"data\").property(\"int\", 6)",
+ "python": "g.add_v('data').property('int', 6)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).project(\"original\", \"multiplied\").by(identity()).by(math(\"_ * 10\"))",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).project(string1, string2).by(__.identity()).by(__.math(string3))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal)).Project<object>(\"original\", \"multiplied\").By(__.Identity()).By(__.Math(\"_ * 10\"))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal)).Project(\"original\", \"multiplied\").By(gremlingo.T__.Identity()).By(gremlingo.T__.Math(\"_ * 10\"))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "python": "g.V().values('int').as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL)).project('original', 'multiplied').by(__.identity()).by(__.math('_ * 10'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectX99X_asNumberXGType_BIGDECIMALX_isXtypeOfXGType_BIGDECIMALXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.inject(99).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).groupCount()",
+ "language": "g.inject(99).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).groupCount()",
+ "anonymized": "g.inject(number0).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).groupCount()",
+ "dotnet": "g.Inject<object>(99).AsNumber(GType.BigDecimal).Is(P.TypeOf(GType.BigDecimal)).GroupCount<object>()",
+ "go": "g.Inject(99).AsNumber(gremlingo.GType.BigDecimal).Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal)).GroupCount()",
+ "groovy": "g.inject(99).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).groupCount()",
+ "java": "g.inject(99).asNumber(GType.BIGDECIMAL).is(P.typeOf(GType.BIGDECIMAL)).groupCount()",
+ "javascript": "g.inject(99).asNumber(GType.bigDecimal).is(P.typeOf(GType.bigDecimal)).groupCount()",
+ "python": "g.inject(99).as_number(GType.BIGDECIMAL).is_(P.type_of(GType.BIGDECIMAL)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_BIGDECIMALXX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.BIGDECIMAL))",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.BIGDECIMAL))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.BIGDECIMAL))",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.BigDecimal))",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.BigDecimal))",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.BIGDECIMAL))",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.BIGDECIMAL))",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.bigDecimal))",
+ "python": "g.V().values('age').is_(P.type_of(GType.BIGDECIMAL))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 456)",
+ "language": "g.addV(\"data\").property(\"int\", 456)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 456)",
+ "go": "g.AddV(\"data\").Property(\"int\", 456)",
+ "groovy": "g.addV(\"data\").property(\"int\", 456)",
+ "java": "g.addV(\"data\").property(\"int\", 456)",
+ "javascript": "g.addV(\"data\").property(\"int\", 456)",
+ "python": "g.add_v('data').property('int', 456)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT))",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT))",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigInt).is(P.typeOf(GType.bigInt))",
+ "python": "g.V().values('int').as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX_mathXmulX1000XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 100)",
+ "language": "g.addV(\"data\").property(\"int\", 100)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 100)",
+ "go": "g.AddV(\"data\").Property(\"int\", 100)",
+ "groovy": "g.addV(\"data\").property(\"int\", 100)",
+ "java": "g.addV(\"data\").property(\"int\", 100)",
+ "javascript": "g.addV(\"data\").property(\"int\", 100)",
+ "python": "g.add_v('data').property('int', 100)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).math(\"_ * 1000\")",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).math(\"_ * 1000\")",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).math(string1)",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt)).Math(\"_ * 1000\")",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt)).Math(\"_ * 1000\")",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).math(\"_ * 1000\")",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).math(\"_ * 1000\")",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigInt).is(P.typeOf(GType.bigInt)).math(\"_ * 1000\")",
+ "python": "g.V().values('int').as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT)).math('_ * 1000')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX_isXeqX42XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 42)",
+ "language": "g.addV(\"data\").property(\"int\", 42)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 42)",
+ "go": "g.AddV(\"data\").Property(\"int\", 42)",
+ "groovy": "g.addV(\"data\").property(\"int\", 42)",
+ "java": "g.addV(\"data\").property(\"int\", 42)",
+ "javascript": "g.addV(\"data\").property(\"int\", 42)",
+ "python": "g.add_v('data').property('int', 42)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).is(P.eq(42))",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).is(P.eq(42))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).is(P.eq(number0))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt)).Is(P.Eq(42))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt)).Is(gremlingo.P.Eq(42))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).is(P.eq(42))",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).is(P.eq(42))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigInt).is(P.typeOf(GType.bigInt)).is(P.eq(42))",
+ "python": "g.V().values('int').as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT)).is_(P.eq(42))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX_sumX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 10).addV(\"data\").property(\"int\", 20).addV(\"data\").property(\"int\", 30)",
+ "language": "g.addV(\"data\").property(\"int\", 10).addV(\"data\").property(\"int\", 20).addV(\"data\").property(\"int\", 30)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 10).AddV((string) \"data\").Property(\"int\", 20).AddV((string) \"data\").Property(\"int\", 30)",
+ "go": "g.AddV(\"data\").Property(\"int\", 10).AddV(\"data\").Property(\"int\", 20).AddV(\"data\").Property(\"int\", 30)",
+ "groovy": "g.addV(\"data\").property(\"int\", 10).addV(\"data\").property(\"int\", 20).addV(\"data\").property(\"int\", 30)",
+ "java": "g.addV(\"data\").property(\"int\", 10).addV(\"data\").property(\"int\", 20).addV(\"data\").property(\"int\", 30)",
+ "javascript": "g.addV(\"data\").property(\"int\", 10).addV(\"data\").property(\"int\", 20).addV(\"data\").property(\"int\", 30)",
+ "python": "g.add_v('data').property('int', 10).add_v('data').property('int', 20).add_v('data').property('int', 30)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).sum()",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).sum()",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).sum()",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt)).Sum<object>()",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt)).Sum()",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).sum()",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).sum()",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigInt).is(P.typeOf(GType.bigInt)).sum()",
+ "python": "g.V().values('int').as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT)).sum_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX_minX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 15).addV(\"data\").property(\"int\", 25)",
+ "language": "g.addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 15).addV(\"data\").property(\"int\", 25)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 5).AddV((string) \"data\").Property(\"int\", 15).AddV((string) \"data\").Property(\"int\", 25)",
+ "go": "g.AddV(\"data\").Property(\"int\", 5).AddV(\"data\").Property(\"int\", 15).AddV(\"data\").Property(\"int\", 25)",
+ "groovy": "g.addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 15).addV(\"data\").property(\"int\", 25)",
+ "java": "g.addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 15).addV(\"data\").property(\"int\", 25)",
+ "javascript": "g.addV(\"data\").property(\"int\", 5).addV(\"data\").property(\"int\", 15).addV(\"data\").property(\"int\", 25)",
+ "python": "g.add_v('data').property('int', 5).add_v('data').property('int', 15).add_v('data').property('int', 25)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).min()",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).min()",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).min()",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt)).Min<object>()",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt)).Min()",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).min()",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).min()",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigInt).is(P.typeOf(GType.bigInt)).min()",
+ "python": "g.V().values('int').as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT)).min_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX_maxX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 100).addV(\"data\").property(\"int\", 200).addV(\"data\").property(\"int\", 300)",
+ "language": "g.addV(\"data\").property(\"int\", 100).addV(\"data\").property(\"int\", 200).addV(\"data\").property(\"int\", 300)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 100).AddV((string) \"data\").Property(\"int\", 200).AddV((string) \"data\").Property(\"int\", 300)",
+ "go": "g.AddV(\"data\").Property(\"int\", 100).AddV(\"data\").Property(\"int\", 200).AddV(\"data\").Property(\"int\", 300)",
+ "groovy": "g.addV(\"data\").property(\"int\", 100).addV(\"data\").property(\"int\", 200).addV(\"data\").property(\"int\", 300)",
+ "java": "g.addV(\"data\").property(\"int\", 100).addV(\"data\").property(\"int\", 200).addV(\"data\").property(\"int\", 300)",
+ "javascript": "g.addV(\"data\").property(\"int\", 100).addV(\"data\").property(\"int\", 200).addV(\"data\").property(\"int\", 300)",
+ "python": "g.add_v('data').property('int', 100).add_v('data').property('int', 200).add_v('data').property('int', 300)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).max()",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).max()",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).max()",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt)).Max<object>()",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt)).Max()",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).max()",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).max()",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigInt).is(P.typeOf(GType.bigInt)).max()",
+ "python": "g.V().values('int').as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT)).max_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX_project_byXidentityX_byXmathXaddX999XXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 50)",
+ "language": "g.addV(\"data\").property(\"int\", 50)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 50)",
+ "go": "g.AddV(\"data\").Property(\"int\", 50)",
+ "groovy": "g.addV(\"data\").property(\"int\", 50)",
+ "java": "g.addV(\"data\").property(\"int\", 50)",
+ "javascript": "g.addV(\"data\").property(\"int\", 50)",
+ "python": "g.add_v('data').property('int', 50)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).project(\"original\", \"added\").by(identity()).by(math(\"_ + 999\"))",
+ "language": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).project(\"original\", \"added\").by(__.identity()).by(__.math(\"_ + 999\"))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).project(string1, string2).by(__.identity()).by(__.math(string3))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt)).Project<object>(\"original\", \"added\").By(__.Identity()).By(__.Math(\"_ + 999\"))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt)).Project(\"original\", \"added\").By(gremlingo.T__.Identity()).By(gremlingo.T__.Math(\"_ + 999\"))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).project(\"original\", \"added\").by(__.identity()).by(__.math(\"_ + 999\"))",
+ "java": "g.V().values(\"int\").asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).project(\"original\", \"added\").by(__.identity()).by(__.math(\"_ + 999\"))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.bigInt).is(P.typeOf(GType.bigInt)).project(\"original\", \"added\").by(__.identity()).by(__.math(\"_ + 999\"))",
+ "python": "g.V().values('int').as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT)).project('original', 'added').by(__.identity()).by(__.math('_ + 999'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectX777X_asNumberXGType_BIGINTX_isXtypeOfXGType_BIGINTXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.inject(777).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).groupCount()",
+ "language": "g.inject(777).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).groupCount()",
+ "anonymized": "g.inject(number0).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).groupCount()",
+ "dotnet": "g.Inject<object>(777).AsNumber(GType.BigInt).Is(P.TypeOf(GType.BigInt)).GroupCount<object>()",
+ "go": "g.Inject(777).AsNumber(gremlingo.GType.BigInt).Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt)).GroupCount()",
+ "groovy": "g.inject(777).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).groupCount()",
+ "java": "g.inject(777).asNumber(GType.BIGINT).is(P.typeOf(GType.BIGINT)).groupCount()",
+ "javascript": "g.inject(777).asNumber(GType.bigInt).is(P.typeOf(GType.bigInt)).groupCount()",
+ "python": "g.inject(777).as_number(GType.BIGINT).is_(P.type_of(GType.BIGINT)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_BIGINTXX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.BIGINT))",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.BIGINT))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.BIGINT))",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.BigInt))",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.BigInt))",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.BIGINT))",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.BIGINT))",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.bigInt))",
+ "python": "g.V().values('age').is_(P.type_of(GType.BIGINT))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BYTEX_isXtypeOfXGType_BYTEXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 5)",
+ "language": "g.addV(\"data\").property(\"int\", 5)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 5)",
+ "go": "g.AddV(\"data\").Property(\"int\", 5)",
+ "groovy": "g.addV(\"data\").property(\"int\", 5)",
+ "java": "g.addV(\"data\").property(\"int\", 5)",
+ "javascript": "g.addV(\"data\").property(\"int\", 5)",
+ "python": "g.add_v('data').property('int', 5)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE))",
+ "language": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.Byte).Is(P.TypeOf(GType.Byte))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.Byte).Is(gremlingo.P.TypeOf(gremlingo.GType.Byte))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE))",
+ "java": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.byte).is(P.typeOf(GType.byte))",
+ "python": "g.V().values('int').as_number(GType.BYTE).is_(P.type_of(GType.BYTE))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BYTEX_isXtypeOfXGType_BYTEXX_mathXaddX20XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 10)",
+ "language": "g.addV(\"data\").property(\"int\", 10)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 10)",
+ "go": "g.AddV(\"data\").Property(\"int\", 10)",
+ "groovy": "g.addV(\"data\").property(\"int\", 10)",
+ "java": "g.addV(\"data\").property(\"int\", 10)",
+ "javascript": "g.addV(\"data\").property(\"int\", 10)",
+ "python": "g.add_v('data').property('int', 10)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).math(\"_ + 20\")",
+ "language": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).math(\"_ + 20\")",
+ "anonymized": "g.V().values(string0).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).math(string1)",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.Byte).Is(P.TypeOf(GType.Byte)).Math(\"_ + 20\")",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.Byte).Is(gremlingo.P.TypeOf(gremlingo.GType.Byte)).Math(\"_ + 20\")",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).math(\"_ + 20\")",
+ "java": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).math(\"_ + 20\")",
+ "javascript": "g.V().values(\"int\").asNumber(GType.byte).is(P.typeOf(GType.byte)).math(\"_ + 20\")",
+ "python": "g.V().values('int').as_number(GType.BYTE).is_(P.type_of(GType.BYTE)).math('_ + 20')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BYTEX_isXtypeOfXGType_BYTEXX_isXltX10XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 7)",
+ "language": "g.addV(\"data\").property(\"int\", 7)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 7)",
+ "go": "g.AddV(\"data\").Property(\"int\", 7)",
+ "groovy": "g.addV(\"data\").property(\"int\", 7)",
+ "java": "g.addV(\"data\").property(\"int\", 7)",
+ "javascript": "g.addV(\"data\").property(\"int\", 7)",
+ "python": "g.add_v('data').property('int', 7)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).is(P.lt(10))",
+ "language": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).is(P.lt(10))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).is(P.lt(number0))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.Byte).Is(P.TypeOf(GType.Byte)).Is(P.Lt(10))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.Byte).Is(gremlingo.P.TypeOf(gremlingo.GType.Byte)).Is(gremlingo.P.Lt(10))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).is(P.lt(10))",
+ "java": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).is(P.lt(10))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.byte).is(P.typeOf(GType.byte)).is(P.lt(10))",
+ "python": "g.V().values('int').as_number(GType.BYTE).is_(P.type_of(GType.BYTE)).is_(P.lt(10))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BYTEX_isXtypeOfXGType_BYTEXX_sumX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3)",
+ "language": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 1).AddV((string) \"data\").Property(\"int\", 2).AddV((string) \"data\").Property(\"int\", 3)",
+ "go": "g.AddV(\"data\").Property(\"int\", 1).AddV(\"data\").Property(\"int\", 2).AddV(\"data\").Property(\"int\", 3)",
+ "groovy": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3)",
+ "java": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3)",
+ "javascript": "g.addV(\"data\").property(\"int\", 1).addV(\"data\").property(\"int\", 2).addV(\"data\").property(\"int\", 3)",
+ "python": "g.add_v('data').property('int', 1).add_v('data').property('int', 2).add_v('data').property('int', 3)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).sum()",
+ "language": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).sum()",
+ "anonymized": "g.V().values(string0).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).sum()",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.Byte).Is(P.TypeOf(GType.Byte)).Sum<object>()",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.Byte).Is(gremlingo.P.TypeOf(gremlingo.GType.Byte)).Sum()",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).sum()",
+ "java": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).sum()",
+ "javascript": "g.V().values(\"int\").asNumber(GType.byte).is(P.typeOf(GType.byte)).sum()",
+ "python": "g.V().values('int').as_number(GType.BYTE).is_(P.type_of(GType.BYTE)).sum_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BYTEX_isXtypeOfXGType_BYTEXX_project_byXidentityX_byXmathXmulX2XXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 8)",
+ "language": "g.addV(\"data\").property(\"int\", 8)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 8)",
+ "go": "g.AddV(\"data\").Property(\"int\", 8)",
+ "groovy": "g.addV(\"data\").property(\"int\", 8)",
+ "java": "g.addV(\"data\").property(\"int\", 8)",
+ "javascript": "g.addV(\"data\").property(\"int\", 8)",
+ "python": "g.add_v('data').property('int', 8)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).project(\"original\", \"doubled\").by(identity()).by(math(\"_ * 2\"))",
+ "language": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).project(\"original\", \"doubled\").by(__.identity()).by(__.math(\"_ * 2\"))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).project(string1, string2).by(__.identity()).by(__.math(string3))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.Byte).Is(P.TypeOf(GType.Byte)).Project<object>(\"original\", \"doubled\").By(__.Identity()).By(__.Math(\"_ * 2\"))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.Byte).Is(gremlingo.P.TypeOf(gremlingo.GType.Byte)).Project(\"original\", \"doubled\").By(gremlingo.T__.Identity()).By(gremlingo.T__.Math(\"_ * 2\"))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).project(\"original\", \"doubled\").by(__.identity()).by(__.math(\"_ * 2\"))",
+ "java": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).project(\"original\", \"doubled\").by(__.identity()).by(__.math(\"_ * 2\"))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.byte).is(P.typeOf(GType.byte)).project(\"original\", \"doubled\").by(__.identity()).by(__.math(\"_ * 2\"))",
+ "python": "g.V().values('int').as_number(GType.BYTE).is_(P.type_of(GType.BYTE)).project('original', 'doubled').by(__.identity()).by(__.math('_ * 2'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXintX_asNumberXGType_BYTEX_isXtypeOfXGType_BYTEXX_chooseXisXeqX12XX_constantXtwelveX_constantXotherXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"int\", 12)",
+ "language": "g.addV(\"data\").property(\"int\", 12)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"int\", 12)",
+ "go": "g.AddV(\"data\").Property(\"int\", 12)",
+ "groovy": "g.addV(\"data\").property(\"int\", 12)",
+ "java": "g.addV(\"data\").property(\"int\", 12)",
+ "javascript": "g.addV(\"data\").property(\"int\", 12)",
+ "python": "g.add_v('data').property('int', 12)"
+ },
+ {
+ "original": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).choose(__.is(P.eq(12)), constant(\"twelve\"), constant(\"other\"))",
+ "language": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).choose(__.is(P.eq(12)), __.constant(\"twelve\"), __.constant(\"other\"))",
+ "anonymized": "g.V().values(string0).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).choose(__.is(P.eq(number0)), __.constant(string1), __.constant(string2))",
+ "dotnet": "g.V().Values<object>(\"int\").AsNumber(GType.Byte).Is(P.TypeOf(GType.Byte)).Choose<object>(__.Is(P.Eq(12)), __.Constant<object>(\"twelve\"), __.Constant<object>(\"other\"))",
+ "go": "g.V().Values(\"int\").AsNumber(gremlingo.GType.Byte).Is(gremlingo.P.TypeOf(gremlingo.GType.Byte)).Choose(gremlingo.T__.Is(gremlingo.P.Eq(12)), gremlingo.T__.Constant(\"twelve\"), gremlingo.T__.Constant(\"other\"))",
+ "groovy": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).choose(__.is(P.eq(12)), __.constant(\"twelve\"), __.constant(\"other\"))",
+ "java": "g.V().values(\"int\").asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).choose(__.is(P.eq(12)), __.constant(\"twelve\"), __.constant(\"other\"))",
+ "javascript": "g.V().values(\"int\").asNumber(GType.byte).is(P.typeOf(GType.byte)).choose(__.is(P.eq(12)), __.constant(\"twelve\"), __.constant(\"other\"))",
+ "python": "g.V().values('int').as_number(GType.BYTE).is_(P.type_of(GType.BYTE)).choose(__.is_(P.eq(12)), __.constant('twelve'), __.constant('other'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectX15X_asNumberXGType_BYTEX_isXtypeOfXGType_BYTEXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.inject(15).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).groupCount()",
+ "language": "g.inject(15).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).groupCount()",
+ "anonymized": "g.inject(number0).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).groupCount()",
+ "dotnet": "g.Inject<object>(15).AsNumber(GType.Byte).Is(P.TypeOf(GType.Byte)).GroupCount<object>()",
+ "go": "g.Inject(15).AsNumber(gremlingo.GType.Byte).Is(gremlingo.P.TypeOf(gremlingo.GType.Byte)).GroupCount()",
+ "groovy": "g.inject(15).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).groupCount()",
+ "java": "g.inject(15).asNumber(GType.BYTE).is(P.typeOf(GType.BYTE)).groupCount()",
+ "javascript": "g.inject(15).asNumber(GType.byte).is(P.typeOf(GType.byte)).groupCount()",
+ "python": "g.inject(15).as_number(GType.BYTE).is_(P.type_of(GType.BYTE)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_BYTEXX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.BYTE))",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.BYTE))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.BYTE))",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Byte))",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Byte))",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.BYTE))",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.BYTE))",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.byte))",
+ "python": "g.V().values('age').is_(P.type_of(GType.BYTE))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdatetimeX_isXtypeOfXGType_DATETIMEXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "language": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "anonymized": "g.addV(string0).property(string1, offsetdatetime0)",
+ "dotnet": "g.AddV((string) \"event\").Property(\"datetime\", DateTimeOffset.Parse(\"2023-08-08T00:00Z\"))",
+ "go": "g.AddV(\"event\").Property(\"datetime\", time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))",
+ "groovy": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "java": "g.addV(\"event\").property(\"datetime\", OffsetDateTime.parse(\"2023-08-08T00:00Z\"))",
+ "javascript": "g.addV(\"event\").property(\"datetime\", new Date('2023-08-08T00:00Z'))",
+ "python": "g.add_v('event').property('datetime', datetime.datetime.fromisoformat('2023-08-08T00:00+00:00'))"
+ },
+ {
+ "original": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME))",
+ "language": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DATETIME))",
+ "dotnet": "g.V().Values<object>(\"datetime\").Is(P.TypeOf(GType.DateTime))",
+ "go": "g.V().Values(\"datetime\").Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime))",
+ "groovy": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME))",
+ "java": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME))",
+ "javascript": "g.V().values(\"datetime\").is(P.typeOf(GType.datetime))",
+ "python": "g.V().values('datetime').is_(P.type_of(GType.DATETIME))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdatetimeX_isXtypeOfXGType_DATETIMEXX_project_byXidentityX_byXdateAddXDT_dayX1XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "language": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "anonymized": "g.addV(string0).property(string1, offsetdatetime0)",
+ "dotnet": "g.AddV((string) \"event\").Property(\"datetime\", DateTimeOffset.Parse(\"2023-08-08T00:00Z\"))",
+ "go": "g.AddV(\"event\").Property(\"datetime\", time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))",
+ "groovy": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "java": "g.addV(\"event\").property(\"datetime\", OffsetDateTime.parse(\"2023-08-08T00:00Z\"))",
+ "javascript": "g.addV(\"event\").property(\"datetime\", new Date('2023-08-08T00:00Z'))",
+ "python": "g.add_v('event').property('datetime', datetime.datetime.fromisoformat('2023-08-08T00:00+00:00'))"
+ },
+ {
+ "original": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).project(\"original\", \"nextDay\").by(identity()).by(dateAdd(DT.day, 1))",
+ "language": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).project(\"original\", \"nextDay\").by(__.identity()).by(__.dateAdd(DT.day, 1))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DATETIME)).project(string1, string2).by(__.identity()).by(__.dateAdd(DT.day, number0))",
+ "dotnet": "g.V().Values<object>(\"datetime\").Is(P.TypeOf(GType.DateTime)).Project<object>(\"original\", \"nextDay\").By(__.Identity()).By(__.DateAdd(DT.Day, 1))",
+ "go": "g.V().Values(\"datetime\").Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime)).Project(\"original\", \"nextDay\").By(gremlingo.T__.Identity()).By(gremlingo.T__.DateAdd(gremlingo.DT.Day, 1))",
+ "groovy": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).project(\"original\", \"nextDay\").by(__.identity()).by(__.dateAdd(DT.day, 1))",
+ "java": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).project(\"original\", \"nextDay\").by(__.identity()).by(__.dateAdd(DT.day, 1))",
+ "javascript": "g.V().values(\"datetime\").is(P.typeOf(GType.datetime)).project(\"original\", \"nextDay\").by(__.identity()).by(__.dateAdd(DT.day, 1))",
+ "python": "g.V().values('datetime').is_(P.type_of(GType.DATETIME)).project('original', 'nextDay').by(__.identity()).by(__.date_add(DT.day, 1))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdatetimeX_isXtypeOfXGType_DATETIMEXX_dateDiffXdatetimeX2023_08_10XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "language": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "anonymized": "g.addV(string0).property(string1, offsetdatetime0)",
+ "dotnet": "g.AddV((string) \"event\").Property(\"datetime\", DateTimeOffset.Parse(\"2023-08-08T00:00Z\"))",
+ "go": "g.AddV(\"event\").Property(\"datetime\", time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))",
+ "groovy": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "java": "g.addV(\"event\").property(\"datetime\", OffsetDateTime.parse(\"2023-08-08T00:00Z\"))",
+ "javascript": "g.addV(\"event\").property(\"datetime\", new Date('2023-08-08T00:00Z'))",
+ "python": "g.add_v('event').property('datetime', datetime.datetime.fromisoformat('2023-08-08T00:00+00:00'))"
+ },
+ {
+ "original": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).dateDiff(datetime(\"2023-08-08T00:00:30Z\"))",
+ "language": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).dateDiff(datetime(\"2023-08-08T00:00:30Z\"))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DATETIME)).dateDiff(offsetdatetime0)",
+ "dotnet": "g.V().Values<object>(\"datetime\").Is(P.TypeOf(GType.DateTime)).DateDiff(DateTimeOffset.Parse(\"2023-08-08T00:00:30Z\"))",
+ "go": "g.V().Values(\"datetime\").Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime)).DateDiff(time.Date(2023, 8, 8, 0, 0, 30, 0, time.FixedZone(\"UTC+00:00\", 0)))",
+ "groovy": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).dateDiff(datetime(\"2023-08-08T00:00:30Z\"))",
+ "java": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).dateDiff(OffsetDateTime.parse(\"2023-08-08T00:00:30Z\"))",
+ "javascript": "g.V().values(\"datetime\").is(P.typeOf(GType.datetime)).dateDiff(new Date('2023-08-08T00:00:30Z'))",
+ "python": "g.V().values('datetime').is_(P.type_of(GType.DATETIME)).date_diff(datetime.datetime.fromisoformat('2023-08-08T00:00:30+00:00'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdatetimeX_isXtypeOfXGType_DATETIMEXX_whereXisXgtXdatetimeX2020_01_01XXXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "language": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "anonymized": "g.addV(string0).property(string1, offsetdatetime0)",
+ "dotnet": "g.AddV((string) \"event\").Property(\"datetime\", DateTimeOffset.Parse(\"2023-08-08T00:00Z\"))",
+ "go": "g.AddV(\"event\").Property(\"datetime\", time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))",
+ "groovy": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "java": "g.addV(\"event\").property(\"datetime\", OffsetDateTime.parse(\"2023-08-08T00:00Z\"))",
+ "javascript": "g.addV(\"event\").property(\"datetime\", new Date('2023-08-08T00:00Z'))",
+ "python": "g.add_v('event').property('datetime', datetime.datetime.fromisoformat('2023-08-08T00:00+00:00'))"
+ },
+ {
+ "original": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).where(__.is(P.gt(datetime(\"2020-01-01T00:00:00Z\"))))",
+ "language": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).where(__.is(P.gt(datetime(\"2020-01-01T00:00:00Z\"))))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DATETIME)).where(__.is(P.gt(offsetdatetime0)))",
+ "dotnet": "g.V().Values<object>(\"datetime\").Is(P.TypeOf(GType.DateTime)).Where(__.Is(P.Gt(DateTimeOffset.Parse(\"2020-01-01T00:00Z\"))))",
+ "go": "g.V().Values(\"datetime\").Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime)).Where(gremlingo.T__.Is(gremlingo.P.Gt(time.Date(2020, 1, 1, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))))",
+ "groovy": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).where(__.is(P.gt(datetime(\"2020-01-01T00:00:00Z\"))))",
+ "java": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).where(__.is(P.gt(OffsetDateTime.parse(\"2020-01-01T00:00Z\"))))",
+ "javascript": "g.V().values(\"datetime\").is(P.typeOf(GType.datetime)).where(__.is(P.gt(new Date('2020-01-01T00:00Z'))))",
+ "python": "g.V().values('datetime').is_(P.type_of(GType.DATETIME)).where(__.is_(P.gt(datetime.datetime.fromisoformat('2020-01-01T00:00+00:00'))))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdatetimeX_isXtypeOfXGType_DATETIMEXX_chooseXisXeqXdatetimeX2023_08_08XXXX_constantXmatchX_constantXnoMatchXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "language": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "anonymized": "g.addV(string0).property(string1, offsetdatetime0)",
+ "dotnet": "g.AddV((string) \"event\").Property(\"datetime\", DateTimeOffset.Parse(\"2023-08-08T00:00Z\"))",
+ "go": "g.AddV(\"event\").Property(\"datetime\", time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))",
+ "groovy": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "java": "g.addV(\"event\").property(\"datetime\", OffsetDateTime.parse(\"2023-08-08T00:00Z\"))",
+ "javascript": "g.addV(\"event\").property(\"datetime\", new Date('2023-08-08T00:00Z'))",
+ "python": "g.add_v('event').property('datetime', datetime.datetime.fromisoformat('2023-08-08T00:00+00:00'))"
+ },
+ {
+ "original": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).choose(__.is(P.eq(datetime(\"2023-08-08T00:00:00Z\"))), constant(\"match\"), constant(\"noMatch\"))",
+ "language": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).choose(__.is(P.eq(datetime(\"2023-08-08T00:00:00Z\"))), __.constant(\"match\"), __.constant(\"noMatch\"))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DATETIME)).choose(__.is(P.eq(offsetdatetime0)), __.constant(string1), __.constant(string2))",
+ "dotnet": "g.V().Values<object>(\"datetime\").Is(P.TypeOf(GType.DateTime)).Choose<object>(__.Is(P.Eq(DateTimeOffset.Parse(\"2023-08-08T00:00Z\"))), __.Constant<object>(\"match\"), __.Constant<object>(\"noMatch\"))",
+ "go": "g.V().Values(\"datetime\").Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime)).Choose(gremlingo.T__.Is(gremlingo.P.Eq(time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))), gremlingo.T__.Constant(\"match\"), gremlingo.T__.Constant(\"noMatch\"))",
+ "groovy": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).choose(__.is(P.eq(datetime(\"2023-08-08T00:00:00Z\"))), __.constant(\"match\"), __.constant(\"noMatch\"))",
+ "java": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).choose(__.is(P.eq(OffsetDateTime.parse(\"2023-08-08T00:00Z\"))), __.constant(\"match\"), __.constant(\"noMatch\"))",
+ "javascript": "g.V().values(\"datetime\").is(P.typeOf(GType.datetime)).choose(__.is(P.eq(new Date('2023-08-08T00:00Z'))), __.constant(\"match\"), __.constant(\"noMatch\"))",
+ "python": "g.V().values('datetime').is_(P.type_of(GType.DATETIME)).choose(__.is_(P.eq(datetime.datetime.fromisoformat('2023-08-08T00:00+00:00'))), __.constant('match'), __.constant('noMatch'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdatetimeX_isXtypeOfXGType_DATETIMEXX_localXaggregateXaX_capXaX",
+ "traversals": [
+ {
+ "original": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "language": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "anonymized": "g.addV(string0).property(string1, offsetdatetime0)",
+ "dotnet": "g.AddV((string) \"event\").Property(\"datetime\", DateTimeOffset.Parse(\"2023-08-08T00:00Z\"))",
+ "go": "g.AddV(\"event\").Property(\"datetime\", time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0)))",
+ "groovy": "g.addV(\"event\").property(\"datetime\", datetime(\"2023-08-08T00:00:00Z\"))",
+ "java": "g.addV(\"event\").property(\"datetime\", OffsetDateTime.parse(\"2023-08-08T00:00Z\"))",
+ "javascript": "g.addV(\"event\").property(\"datetime\", new Date('2023-08-08T00:00Z'))",
+ "python": "g.add_v('event').property('datetime', datetime.datetime.fromisoformat('2023-08-08T00:00+00:00'))"
+ },
+ {
+ "original": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).local(aggregate(\"a\")).cap(\"a\")",
+ "language": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DATETIME)).local(__.aggregate(string1)).cap(string1)",
+ "dotnet": "g.V().Values<object>(\"datetime\").Is(P.TypeOf(GType.DateTime)).Local<object>(__.Aggregate(\"a\")).Cap<object>(\"a\")",
+ "go": "g.V().Values(\"datetime\").Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime)).Local(gremlingo.T__.Aggregate(\"a\")).Cap(\"a\")",
+ "groovy": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "java": "g.V().values(\"datetime\").is(P.typeOf(GType.DATETIME)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "javascript": "g.V().values(\"datetime\").is(P.typeOf(GType.datetime)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "python": "g.V().values('datetime').is_(P.type_of(GType.DATETIME)).local(__.aggregate('a')).cap('a')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectXdatetimeX_isXtypeOfXGType_DATETIMEXX_aggregateXaX_capXaX",
+ "traversals": [
+ {
+ "original": "g.inject(datetime(\"2023-08-08T00:00:00Z\")).is(P.typeOf(GType.DATETIME)).aggregate(\"a\").cap(\"a\")",
+ "language": "g.inject(datetime(\"2023-08-08T00:00:00Z\")).is(P.typeOf(GType.DATETIME)).aggregate(\"a\").cap(\"a\")",
+ "anonymized": "g.inject(offsetdatetime0).is(P.typeOf(GType.DATETIME)).aggregate(string0).cap(string0)",
+ "dotnet": "g.Inject<object>(DateTimeOffset.Parse(\"2023-08-08T00:00Z\")).Is(P.TypeOf(GType.DateTime)).Aggregate(\"a\").Cap<object>(\"a\")",
+ "go": "g.Inject(time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0))).Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime)).Aggregate(\"a\").Cap(\"a\")",
+ "groovy": "g.inject(datetime(\"2023-08-08T00:00:00Z\")).is(P.typeOf(GType.DATETIME)).aggregate(\"a\").cap(\"a\")",
+ "java": "g.inject(OffsetDateTime.parse(\"2023-08-08T00:00Z\")).is(P.typeOf(GType.DATETIME)).aggregate(\"a\").cap(\"a\")",
+ "javascript": "g.inject(new Date('2023-08-08T00:00Z')).is(P.typeOf(GType.datetime)).aggregate(\"a\").cap(\"a\")",
+ "python": "g.inject(datetime.datetime.fromisoformat('2023-08-08T00:00+00:00')).is_(P.type_of(GType.DATETIME)).aggregate('a').cap('a')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectXdatetimeX_isXtypeOfXGType_DATETIMEXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.inject(datetime(\"2023-08-08T00:00:00Z\")).is(P.typeOf(GType.DATETIME)).groupCount()",
+ "language": "g.inject(datetime(\"2023-08-08T00:00:00Z\")).is(P.typeOf(GType.DATETIME)).groupCount()",
+ "anonymized": "g.inject(offsetdatetime0).is(P.typeOf(GType.DATETIME)).groupCount()",
+ "dotnet": "g.Inject<object>(DateTimeOffset.Parse(\"2023-08-08T00:00Z\")).Is(P.TypeOf(GType.DateTime)).GroupCount<object>()",
+ "go": "g.Inject(time.Date(2023, 8, 8, 0, 0, 0, 0, time.FixedZone(\"UTC+00:00\", 0))).Is(gremlingo.P.TypeOf(gremlingo.GType.DateTime)).GroupCount()",
+ "groovy": "g.inject(datetime(\"2023-08-08T00:00:00Z\")).is(P.typeOf(GType.DATETIME)).groupCount()",
+ "java": "g.inject(OffsetDateTime.parse(\"2023-08-08T00:00Z\")).is(P.typeOf(GType.DATETIME)).groupCount()",
+ "javascript": "g.inject(new Date('2023-08-08T00:00Z')).is(P.typeOf(GType.datetime)).groupCount()",
+ "python": "g.inject(datetime.datetime.fromisoformat('2023-08-08T00:00+00:00')).is_(P.type_of(GType.DATETIME)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 1.5d)",
+ "language": "g.addV(\"data\").property(\"double\", 1.5d)",
+ "anonymized": "g.addV(string0).property(string1, double0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 1.5d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 1.5)",
+ "groovy": "g.addV(\"data\").property(\"double\", 1.5d)",
+ "java": "g.addV(\"data\").property(\"double\", 1.5d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 1.5)",
+ "python": "g.add_v('data').property('double', 1.5)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE))",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE))",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double))",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double))",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE))",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE))",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double))",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_E_valuesXweightX_isXtypeOfXGType_DOUBLEXX",
+ "traversals": [
+ {
+ "original": "g.E().values(\"weight\").is(P.typeOf(GType.DOUBLE))",
+ "language": "g.E().values(\"weight\").is(P.typeOf(GType.DOUBLE))",
+ "anonymized": "g.E().values(string0).is(P.typeOf(GType.DOUBLE))",
+ "dotnet": "g.E().Values<object>(\"weight\").Is(P.TypeOf(GType.Double))",
+ "go": "g.E().Values(\"weight\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double))",
+ "groovy": "g.E().values(\"weight\").is(P.typeOf(GType.DOUBLE))",
+ "java": "g.E().values(\"weight\").is(P.typeOf(GType.DOUBLE))",
+ "javascript": "g.E().values(\"weight\").is(P.typeOf(GType.double))",
+ "python": "g.E().values('weight').is_(P.type_of(GType.DOUBLE))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_mathXceilX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 2.7d)",
+ "language": "g.addV(\"data\").property(\"double\", 2.7d)",
+ "anonymized": "g.addV(string0).property(string1, double0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 2.7d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 2.7)",
+ "groovy": "g.addV(\"data\").property(\"double\", 2.7d)",
+ "java": "g.addV(\"data\").property(\"double\", 2.7d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 2.7)",
+ "python": "g.add_v('data').property('double', 2.7)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).math('ceil _')",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).math('ceil _')",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE)).math(string1)",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double)).Math(\"ceil _\")",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Math(\"ceil _\")",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).math('ceil _')",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).math(\"ceil _\")",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double)).math(\"ceil _\")",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE)).math('ceil _')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_isXgtX1_0XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 0.8d).addV(\"data\").property(\"double\", 1.2d)",
+ "language": "g.addV(\"data\").property(\"double\", 0.8d).addV(\"data\").property(\"double\", 1.2d)",
+ "anonymized": "g.addV(string0).property(string1, double0).addV(string0).property(string1, double1)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 0.8d).AddV((string) \"data\").Property(\"double\", 1.2d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 0.8).AddV(\"data\").Property(\"double\", 1.2)",
+ "groovy": "g.addV(\"data\").property(\"double\", 0.8d).addV(\"data\").property(\"double\", 1.2d)",
+ "java": "g.addV(\"data\").property(\"double\", 0.8d).addV(\"data\").property(\"double\", 1.2d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 0.8).addV(\"data\").property(\"double\", 1.2)",
+ "python": "g.add_v('data').property('double', 0.8).add_v('data').property('double', 1.2)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).is(P.gt(1.0d))",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).is(P.gt(1.0d))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE)).is(P.gt(double0))",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double)).Is(P.Gt(1.0d))",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Is(gremlingo.P.Gt(1.0))",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).is(P.gt(1.0d))",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).is(P.gt(1.0d))",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double)).is(P.gt(1.0))",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE)).is_(P.gt(1.0))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_sumX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 1.5d).addV(\"data\").property(\"double\", 2.5d).addV(\"data\").property(\"double\", 3.5d)",
+ "language": "g.addV(\"data\").property(\"double\", 1.5d).addV(\"data\").property(\"double\", 2.5d).addV(\"data\").property(\"double\", 3.5d)",
+ "anonymized": "g.addV(string0).property(string1, double0).addV(string0).property(string1, double1).addV(string0).property(string1, double2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 1.5d).AddV((string) \"data\").Property(\"double\", 2.5d).AddV((string) \"data\").Property(\"double\", 3.5d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 1.5).AddV(\"data\").Property(\"double\", 2.5).AddV(\"data\").Property(\"double\", 3.5)",
+ "groovy": "g.addV(\"data\").property(\"double\", 1.5d).addV(\"data\").property(\"double\", 2.5d).addV(\"data\").property(\"double\", 3.5d)",
+ "java": "g.addV(\"data\").property(\"double\", 1.5d).addV(\"data\").property(\"double\", 2.5d).addV(\"data\").property(\"double\", 3.5d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 1.5).addV(\"data\").property(\"double\", 2.5).addV(\"data\").property(\"double\", 3.5)",
+ "python": "g.add_v('data').property('double', 1.5).add_v('data').property('double', 2.5).add_v('data').property('double', 3.5)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).sum()",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).sum()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE)).sum()",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double)).Sum<object>()",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Sum()",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).sum()",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).sum()",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double)).sum()",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE)).sum_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_minX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 0.1d).addV(\"data\").property(\"double\", 0.5d).addV(\"data\").property(\"double\", 0.9d)",
+ "language": "g.addV(\"data\").property(\"double\", 0.1d).addV(\"data\").property(\"double\", 0.5d).addV(\"data\").property(\"double\", 0.9d)",
+ "anonymized": "g.addV(string0).property(string1, double0).addV(string0).property(string1, double1).addV(string0).property(string1, double2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 0.1d).AddV((string) \"data\").Property(\"double\", 0.5d).AddV((string) \"data\").Property(\"double\", 0.9d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 0.1).AddV(\"data\").Property(\"double\", 0.5).AddV(\"data\").Property(\"double\", 0.9)",
+ "groovy": "g.addV(\"data\").property(\"double\", 0.1d).addV(\"data\").property(\"double\", 0.5d).addV(\"data\").property(\"double\", 0.9d)",
+ "java": "g.addV(\"data\").property(\"double\", 0.1d).addV(\"data\").property(\"double\", 0.5d).addV(\"data\").property(\"double\", 0.9d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 0.1).addV(\"data\").property(\"double\", 0.5).addV(\"data\").property(\"double\", 0.9)",
+ "python": "g.add_v('data').property('double', 0.1).add_v('data').property('double', 0.5).add_v('data').property('double', 0.9)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).min()",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).min()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE)).min()",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double)).Min<object>()",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Min()",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).min()",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).min()",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double)).min()",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE)).min_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_maxX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 3.7d).addV(\"data\").property(\"double\", 1.9d)",
+ "language": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 3.7d).addV(\"data\").property(\"double\", 1.9d)",
+ "anonymized": "g.addV(string0).property(string1, double0).addV(string0).property(string1, double1).addV(string0).property(string1, double2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 2.1d).AddV((string) \"data\").Property(\"double\", 3.7d).AddV((string) \"data\").Property(\"double\", 1.9d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 2.1).AddV(\"data\").Property(\"double\", 3.7).AddV(\"data\").Property(\"double\", 1.9)",
+ "groovy": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 3.7d).addV(\"data\").property(\"double\", 1.9d)",
+ "java": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 3.7d).addV(\"data\").property(\"double\", 1.9d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 2.1).addV(\"data\").property(\"double\", 3.7).addV(\"data\").property(\"double\", 1.9)",
+ "python": "g.add_v('data').property('double', 2.1).add_v('data').property('double', 3.7).add_v('data').property('double', 1.9)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).max()",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).max()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE)).max()",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double)).Max<object>()",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Max()",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).max()",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).max()",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double)).max()",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE)).max_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_meanX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 4.1d).addV(\"data\").property(\"double\", 6.1d)",
+ "language": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 4.1d).addV(\"data\").property(\"double\", 6.1d)",
+ "anonymized": "g.addV(string0).property(string1, double0).addV(string0).property(string1, double1).addV(string0).property(string1, double2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 2.1d).AddV((string) \"data\").Property(\"double\", 4.1d).AddV((string) \"data\").Property(\"double\", 6.1d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 2.1).AddV(\"data\").Property(\"double\", 4.1).AddV(\"data\").Property(\"double\", 6.1)",
+ "groovy": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 4.1d).addV(\"data\").property(\"double\", 6.1d)",
+ "java": "g.addV(\"data\").property(\"double\", 2.1d).addV(\"data\").property(\"double\", 4.1d).addV(\"data\").property(\"double\", 6.1d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 2.1).addV(\"data\").property(\"double\", 4.1).addV(\"data\").property(\"double\", 6.1)",
+ "python": "g.add_v('data').property('double', 2.1).add_v('data').property('double', 4.1).add_v('data').property('double', 6.1)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).mean()",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).mean()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE)).mean()",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double)).Mean<object>()",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Mean()",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).mean()",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).mean()",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double)).mean()",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE)).mean()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXdoubleX_isXtypeOfXGType_DOUBLEXX_order_byXascX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"double\", 3.2d).addV(\"data\").property(\"double\", 1.8d).addV(\"data\").property(\"double\", 2.5d)",
+ "language": "g.addV(\"data\").property(\"double\", 3.2d).addV(\"data\").property(\"double\", 1.8d).addV(\"data\").property(\"double\", 2.5d)",
+ "anonymized": "g.addV(string0).property(string1, double0).addV(string0).property(string1, double1).addV(string0).property(string1, double2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"double\", 3.2d).AddV((string) \"data\").Property(\"double\", 1.8d).AddV((string) \"data\").Property(\"double\", 2.5d)",
+ "go": "g.AddV(\"data\").Property(\"double\", 3.2).AddV(\"data\").Property(\"double\", 1.8).AddV(\"data\").Property(\"double\", 2.5)",
+ "groovy": "g.addV(\"data\").property(\"double\", 3.2d).addV(\"data\").property(\"double\", 1.8d).addV(\"data\").property(\"double\", 2.5d)",
+ "java": "g.addV(\"data\").property(\"double\", 3.2d).addV(\"data\").property(\"double\", 1.8d).addV(\"data\").property(\"double\", 2.5d)",
+ "javascript": "g.addV(\"data\").property(\"double\", 3.2).addV(\"data\").property(\"double\", 1.8).addV(\"data\").property(\"double\", 2.5)",
+ "python": "g.add_v('data').property('double', 3.2).add_v('data').property('double', 1.8).add_v('data').property('double', 2.5)"
+ },
+ {
+ "original": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).order().by(asc)",
+ "language": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).order().by(Order.asc)",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE)).order().by(Order.asc)",
+ "dotnet": "g.V().Values<object>(\"double\").Is(P.TypeOf(GType.Double)).Order().By(Order.Asc)",
+ "go": "g.V().Values(\"double\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).Order().By(gremlingo.Order.Asc)",
+ "groovy": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).order().by(Order.asc)",
+ "java": "g.V().values(\"double\").is(P.typeOf(GType.DOUBLE)).order().by(Order.asc)",
+ "javascript": "g.V().values(\"double\").is(P.typeOf(GType.double)).order().by(Order.asc)",
+ "python": "g.V().values('double').is_(P.type_of(GType.DOUBLE)).order().by(Order.asc)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectX5_5dX_isXtypeOfXGType_DOUBLEXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.inject(5.5d).is(P.typeOf(GType.DOUBLE)).groupCount()",
+ "language": "g.inject(5.5d).is(P.typeOf(GType.DOUBLE)).groupCount()",
+ "anonymized": "g.inject(double0).is(P.typeOf(GType.DOUBLE)).groupCount()",
+ "dotnet": "g.Inject<object>(5.5d).Is(P.TypeOf(GType.Double)).GroupCount<object>()",
+ "go": "g.Inject(5.5).Is(gremlingo.P.TypeOf(gremlingo.GType.Double)).GroupCount()",
+ "groovy": "g.inject(5.5d).is(P.typeOf(GType.DOUBLE)).groupCount()",
+ "java": "g.inject(5.5d).is(P.typeOf(GType.DOUBLE)).groupCount()",
+ "javascript": "g.inject(5.5).is(P.typeOf(GType.double)).groupCount()",
+ "python": "g.inject(5.5).is_(P.type_of(GType.DOUBLE)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_DOUBLEXX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.DOUBLE))",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.DOUBLE))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.DOUBLE))",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Double))",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Double))",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.DOUBLE))",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.DOUBLE))",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.double))",
+ "python": "g.V().values('age').is_(P.type_of(GType.DOUBLE))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"float\", 2.5)",
+ "language": "g.addV(\"data\").property(\"float\", 2.5)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"float\", 2.5)",
+ "go": "g.AddV(\"data\").Property(\"float\", 2.5)",
+ "groovy": "g.addV(\"data\").property(\"float\", 2.5)",
+ "java": "g.addV(\"data\").property(\"float\", 2.5)",
+ "javascript": "g.addV(\"data\").property(\"float\", 2.5)",
+ "python": "g.add_v('data').property('float', 2.5)"
+ },
+ {
+ "original": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT))",
+ "language": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT))",
+ "anonymized": "g.V().values(string0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT))",
+ "dotnet": "g.V().Values<object>(\"float\").AsNumber(GType.Float).Is(P.TypeOf(GType.Float))",
+ "go": "g.V().Values(\"float\").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float))",
+ "groovy": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT))",
+ "java": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT))",
+ "javascript": "g.V().values(\"float\").asNumber(GType.float).is(P.typeOf(GType.float))",
+ "python": "g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_mathXmulX2XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"float\", 3.0)",
+ "language": "g.addV(\"data\").property(\"float\", 3.0)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"float\", 3.0)",
+ "go": "g.AddV(\"data\").Property(\"float\", 3.0)",
+ "groovy": "g.addV(\"data\").property(\"float\", 3.0)",
+ "java": "g.addV(\"data\").property(\"float\", 3.0)",
+ "javascript": "g.addV(\"data\").property(\"float\", 3.0)",
+ "python": "g.add_v('data').property('float', 3.0)"
+ },
+ {
+ "original": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).math(\"_ * 2\")",
+ "language": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).math(\"_ * 2\")",
+ "anonymized": "g.V().values(string0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).math(string1)",
+ "dotnet": "g.V().Values<object>(\"float\").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Math(\"_ * 2\")",
+ "go": "g.V().Values(\"float\").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Math(\"_ * 2\")",
+ "groovy": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).math(\"_ * 2\")",
+ "java": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).math(\"_ * 2\")",
+ "javascript": "g.V().values(\"float\").asNumber(GType.float).is(P.typeOf(GType.float)).math(\"_ * 2\")",
+ "python": "g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).math('_ * 2')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_isXeqX1_5XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"float\", 1.5)",
+ "language": "g.addV(\"data\").property(\"float\", 1.5)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"float\", 1.5)",
+ "go": "g.AddV(\"data\").Property(\"float\", 1.5)",
+ "groovy": "g.addV(\"data\").property(\"float\", 1.5)",
+ "java": "g.addV(\"data\").property(\"float\", 1.5)",
+ "javascript": "g.addV(\"data\").property(\"float\", 1.5)",
+ "python": "g.add_v('data').property('float', 1.5)"
+ },
+ {
+ "original": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).is(P.eq(1.5))",
+ "language": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).is(P.eq(1.5))",
+ "anonymized": "g.V().values(string0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).is(P.eq(number0))",
+ "dotnet": "g.V().Values<object>(\"float\").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Is(P.Eq(1.5))",
+ "go": "g.V().Values(\"float\").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Is(gremlingo.P.Eq(1.5))",
+ "groovy": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).is(P.eq(1.5))",
+ "java": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).is(P.eq(1.5))",
+ "javascript": "g.V().values(\"float\").asNumber(GType.float).is(P.typeOf(GType.float)).is(P.eq(1.5))",
+ "python": "g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).is_(P.eq(1.5))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_sumX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"float\", 1.5).addV(\"data\").property(\"float\", 2.5).addV(\"data\").property(\"float\", 3.0)",
+ "language": "g.addV(\"data\").property(\"float\", 1.5).addV(\"data\").property(\"float\", 2.5).addV(\"data\").property(\"float\", 3.0)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1).addV(string0).property(string1, number2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"float\", 1.5).AddV((string) \"data\").Property(\"float\", 2.5).AddV((string) \"data\").Property(\"float\", 3.0)",
+ "go": "g.AddV(\"data\").Property(\"float\", 1.5).AddV(\"data\").Property(\"float\", 2.5).AddV(\"data\").Property(\"float\", 3.0)",
+ "groovy": "g.addV(\"data\").property(\"float\", 1.5).addV(\"data\").property(\"float\", 2.5).addV(\"data\").property(\"float\", 3.0)",
+ "java": "g.addV(\"data\").property(\"float\", 1.5).addV(\"data\").property(\"float\", 2.5).addV(\"data\").property(\"float\", 3.0)",
+ "javascript": "g.addV(\"data\").property(\"float\", 1.5).addV(\"data\").property(\"float\", 2.5).addV(\"data\").property(\"float\", 3.0)",
+ "python": "g.add_v('data').property('float', 1.5).add_v('data').property('float', 2.5).add_v('data').property('float', 3.0)"
+ },
+ {
+ "original": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).sum()",
+ "language": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).sum()",
+ "anonymized": "g.V().values(string0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).sum()",
+ "dotnet": "g.V().Values<object>(\"float\").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Sum<object>()",
+ "go": "g.V().Values(\"float\").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Sum()",
+ "groovy": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).sum()",
+ "java": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).sum()",
+ "javascript": "g.V().values(\"float\").asNumber(GType.float).is(P.typeOf(GType.float)).sum()",
+ "python": "g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).sum_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_project_byXidentityX_byXmathXmulX10XXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"float\", 4.5)",
+ "language": "g.addV(\"data\").property(\"float\", 4.5)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"float\", 4.5)",
+ "go": "g.AddV(\"data\").Property(\"float\", 4.5)",
+ "groovy": "g.addV(\"data\").property(\"float\", 4.5)",
+ "java": "g.addV(\"data\").property(\"float\", 4.5)",
+ "javascript": "g.addV(\"data\").property(\"float\", 4.5)",
+ "python": "g.add_v('data').property('float', 4.5)"
+ },
+ {
+ "original": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).project(\"original\", \"multiplied\").by(identity()).by(math(\"_ * 10\"))",
+ "language": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "anonymized": "g.V().values(string0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).project(string1, string2).by(__.identity()).by(__.math(string3))",
+ "dotnet": "g.V().Values<object>(\"float\").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Project<object>(\"original\", \"multiplied\").By(__.Identity()).By(__.Math(\"_ * 10\"))",
+ "go": "g.V().Values(\"float\").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Project(\"original\", \"multiplied\").By(gremlingo.T__.Identity()).By(gremlingo.T__.Math(\"_ * 10\"))",
+ "groovy": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "java": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "javascript": "g.V().values(\"float\").asNumber(GType.float).is(P.typeOf(GType.float)).project(\"original\", \"multiplied\").by(__.identity()).by(__.math(\"_ * 10\"))",
+ "python": "g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).project('original', 'multiplied').by(__.identity()).by(__.math('_ * 10'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_whereXisXgtX1_0XXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"float\", 0.5).addV(\"data\").property(\"float\", 1.5)",
+ "language": "g.addV(\"data\").property(\"float\", 0.5).addV(\"data\").property(\"float\", 1.5)",
+ "anonymized": "g.addV(string0).property(string1, number0).addV(string0).property(string1, number1)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"float\", 0.5).AddV((string) \"data\").Property(\"float\", 1.5)",
+ "go": "g.AddV(\"data\").Property(\"float\", 0.5).AddV(\"data\").Property(\"float\", 1.5)",
+ "groovy": "g.addV(\"data\").property(\"float\", 0.5).addV(\"data\").property(\"float\", 1.5)",
+ "java": "g.addV(\"data\").property(\"float\", 0.5).addV(\"data\").property(\"float\", 1.5)",
+ "javascript": "g.addV(\"data\").property(\"float\", 0.5).addV(\"data\").property(\"float\", 1.5)",
+ "python": "g.add_v('data').property('float', 0.5).add_v('data').property('float', 1.5)"
+ },
+ {
+ "original": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).where(__.is(P.gt(1.0)))",
+ "language": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).where(__.is(P.gt(1.0)))",
+ "anonymized": "g.V().values(string0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).where(__.is(P.gt(number0)))",
+ "dotnet": "g.V().Values<object>(\"float\").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Where(__.Is(P.Gt(1.0)))",
+ "go": "g.V().Values(\"float\").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Where(gremlingo.T__.Is(gremlingo.P.Gt(1.0)))",
+ "groovy": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).where(__.is(P.gt(1.0)))",
+ "java": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).where(__.is(P.gt(1.0)))",
+ "javascript": "g.V().values(\"float\").asNumber(GType.float).is(P.typeOf(GType.float)).where(__.is(P.gt(1.0)))",
+ "python": "g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).where(__.is_(P.gt(1.0)))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXfloatX_isXtypeOfXGType_FLOATXX_chooseXisXeqX3_0XX_constantXthreeX_constantXotherXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"float\", 3.0)",
+ "language": "g.addV(\"data\").property(\"float\", 3.0)",
+ "anonymized": "g.addV(string0).property(string1, number0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"float\", 3.0)",
+ "go": "g.AddV(\"data\").Property(\"float\", 3.0)",
+ "groovy": "g.addV(\"data\").property(\"float\", 3.0)",
+ "java": "g.addV(\"data\").property(\"float\", 3.0)",
+ "javascript": "g.addV(\"data\").property(\"float\", 3.0)",
+ "python": "g.add_v('data').property('float', 3.0)"
+ },
+ {
+ "original": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).choose(__.is(P.eq(3.0)), constant(\"three\"), constant(\"other\"))",
+ "language": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).choose(__.is(P.eq(3.0)), __.constant(\"three\"), __.constant(\"other\"))",
+ "anonymized": "g.V().values(string0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).choose(__.is(P.eq(number0)), __.constant(string1), __.constant(string2))",
+ "dotnet": "g.V().Values<object>(\"float\").AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).Choose<object>(__.Is(P.Eq(3.0)), __.Constant<object>(\"three\"), __.Constant<object>(\"other\"))",
+ "go": "g.V().Values(\"float\").AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).Choose(gremlingo.T__.Is(gremlingo.P.Eq(3.0)), gremlingo.T__.Constant(\"three\"), gremlingo.T__.Constant(\"other\"))",
+ "groovy": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).choose(__.is(P.eq(3.0)), __.constant(\"three\"), __.constant(\"other\"))",
+ "java": "g.V().values(\"float\").asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).choose(__.is(P.eq(3.0)), __.constant(\"three\"), __.constant(\"other\"))",
+ "javascript": "g.V().values(\"float\").asNumber(GType.float).is(P.typeOf(GType.float)).choose(__.is(P.eq(3.0)), __.constant(\"three\"), __.constant(\"other\"))",
+ "python": "g.V().values('float').as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).choose(__.is_(P.eq(3.0)), __.constant('three'), __.constant('other'))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectX2_0fX_isXtypeOfXGType_FLOATXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.inject(2.0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).groupCount()",
+ "language": "g.inject(2.0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).groupCount()",
+ "anonymized": "g.inject(number0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).groupCount()",
+ "dotnet": "g.Inject<object>(2.0).AsNumber(GType.Float).Is(P.TypeOf(GType.Float)).GroupCount<object>()",
+ "go": "g.Inject(2.0).AsNumber(gremlingo.GType.Float).Is(gremlingo.P.TypeOf(gremlingo.GType.Float)).GroupCount()",
+ "groovy": "g.inject(2.0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).groupCount()",
+ "java": "g.inject(2.0).asNumber(GType.FLOAT).is(P.typeOf(GType.FLOAT)).groupCount()",
+ "javascript": "g.inject(2.0).asNumber(GType.float).is(P.typeOf(GType.float)).groupCount()",
+ "python": "g.inject(2.0).as_number(GType.FLOAT).is_(P.type_of(GType.FLOAT)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_FLOATXX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.FLOAT))",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.FLOAT))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.FLOAT))",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Float))",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Float))",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.FLOAT))",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.FLOAT))",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.float))",
+ "python": "g.V().values('age').is_(P.type_of(GType.FLOAT))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.INT))",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.INT))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.INT))",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Int))",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int))",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.INT))",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.INT))",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.int))",
+ "python": "g.V().values('age').is_(P.type_of(GType.INT))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXage_typeOfXGType_INTXX_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V().has(\"age\", P.typeOf(GType.INT)).values(\"name\")",
+ "language": "g.V().has(\"age\", P.typeOf(GType.INT)).values(\"name\")",
+ "anonymized": "g.V().has(string0, P.typeOf(GType.INT)).values(string1)",
+ "dotnet": "g.V().Has(\"age\", P.TypeOf(GType.Int)).Values<object>(\"name\")",
+ "go": "g.V().Has(\"age\", gremlingo.P.TypeOf(gremlingo.GType.Int)).Values(\"name\")",
+ "groovy": "g.V().has(\"age\", P.typeOf(GType.INT)).values(\"name\")",
+ "java": "g.V().has(\"age\", P.typeOf(GType.INT)).values(\"name\")",
+ "javascript": "g.V().has(\"age\", P.typeOf(GType.int)).values(\"name\")",
+ "python": "g.V().has('age', P.type_of(GType.INT)).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_whereXvaluesXageX_isXtypeOfXGType_INTXXX_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.V().where(__.values(\"age\").is(P.typeOf(GType.INT))).values(\"name\")",
+ "language": "g.V().where(__.values(\"age\").is(P.typeOf(GType.INT))).values(\"name\")",
+ "anonymized": "g.V().where(__.values(string0).is(P.typeOf(GType.INT))).values(string1)",
+ "dotnet": "g.V().Where(__.Values<object>(\"age\").Is(P.TypeOf(GType.Int))).Values<object>(\"name\")",
+ "go": "g.V().Where(gremlingo.T__.Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int))).Values(\"name\")",
+ "groovy": "g.V().where(__.values(\"age\").is(P.typeOf(GType.INT))).values(\"name\")",
+ "java": "g.V().where(__.values(\"age\").is(P.typeOf(GType.INT))).values(\"name\")",
+ "javascript": "g.V().where(__.values(\"age\").is(P.typeOf(GType.int))).values(\"name\")",
+ "python": "g.V().where(__.values('age').is_(P.type_of(GType.INT))).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX_mathXincX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"name\", \"age\").is(P.typeOf(GType.INT)).math(\"_ + 1\")",
+ "language": "g.V().values(\"name\", \"age\").is(P.typeOf(GType.INT)).math(\"_ + 1\")",
+ "anonymized": "g.V().values(string0, string1).is(P.typeOf(GType.INT)).math(string2)",
+ "dotnet": "g.V().Values<object>(\"name\", \"age\").Is(P.TypeOf(GType.Int)).Math(\"_ + 1\")",
+ "go": "g.V().Values(\"name\", \"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int)).Math(\"_ + 1\")",
+ "groovy": "g.V().values(\"name\", \"age\").is(P.typeOf(GType.INT)).math(\"_ + 1\")",
+ "java": "g.V().values(\"name\", \"age\").is(P.typeOf(GType.INT)).math(\"_ + 1\")",
+ "javascript": "g.V().values(\"name\", \"age\").is(P.typeOf(GType.int)).math(\"_ + 1\")",
+ "python": "g.V().values('name', 'age').is_(P.type_of(GType.INT)).math('_ + 1')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX_sumX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.INT)).sum()",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.INT)).sum()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.INT)).sum()",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Int)).Sum<object>()",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int)).Sum()",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.INT)).sum()",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.INT)).sum()",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.int)).sum()",
+ "python": "g.V().values('age').is_(P.type_of(GType.INT)).sum_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX_minX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.INT)).min()",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.INT)).min()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.INT)).min()",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Int)).Min<object>()",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int)).Min()",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.INT)).min()",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.INT)).min()",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.int)).min()",
+ "python": "g.V().values('age').is_(P.type_of(GType.INT)).min_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX_maxX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.INT)).max()",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.INT)).max()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.INT)).max()",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Int)).Max<object>()",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int)).Max()",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.INT)).max()",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.INT)).max()",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.int)).max()",
+ "python": "g.V().values('age').is_(P.type_of(GType.INT)).max_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX_meanX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.INT)).mean()",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.INT)).mean()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.INT)).mean()",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Int)).Mean<object>()",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int)).Mean()",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.INT)).mean()",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.INT)).mean()",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.int)).mean()",
+ "python": "g.V().values('age').is_(P.type_of(GType.INT)).mean()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX_order_byXdescX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.INT)).order().by(desc)",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.INT)).order().by(Order.desc)",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.INT)).order().by(Order.desc)",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Int)).Order().By(Order.Desc)",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int)).Order().By(gremlingo.Order.Desc)",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.INT)).order().by(Order.desc)",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.INT)).order().by(Order.desc)",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.int)).order().by(Order.desc)",
+ "python": "g.V().values('age').is_(P.type_of(GType.INT)).order().by(Order.desc)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_INTXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.INT)).groupCount()",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.INT)).groupCount()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.INT)).groupCount()",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.Int)).GroupCount<object>()",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.Int)).GroupCount()",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.INT)).groupCount()",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.INT)).groupCount()",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.int)).groupCount()",
+ "python": "g.V().values('age').is_(P.type_of(GType.INT)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXnameX_fold_isXtypeOfXGType_LISTXX_count",
+ "traversals": [
+ {
+ "original": "g.V().values(\"name\").fold().is(P.typeOf(GType.LIST)).count()",
+ "language": "g.V().values(\"name\").fold().is(P.typeOf(GType.LIST)).count()",
+ "anonymized": "g.V().values(string0).fold().is(P.typeOf(GType.LIST)).count()",
+ "dotnet": "g.V().Values<object>(\"name\").Fold().Is(P.TypeOf(GType.List)).Count()",
+ "go": "g.V().Values(\"name\").Fold().Is(gremlingo.P.TypeOf(gremlingo.GType.List)).Count()",
+ "groovy": "g.V().values(\"name\").fold().is(P.typeOf(GType.LIST)).count()",
+ "java": "g.V().values(\"name\").fold().is(P.typeOf(GType.LIST)).count()",
+ "javascript": "g.V().values(\"name\").fold().is(P.typeOf(GType.list)).count()",
+ "python": "g.V().values('name').fold().is_(P.type_of(GType.LIST)).count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXageX_isXtypeOfXGType_LISTXX",
+ "traversals": [
+ {
+ "original": "g.V().values(\"age\").is(P.typeOf(GType.LIST))",
+ "language": "g.V().values(\"age\").is(P.typeOf(GType.LIST))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LIST))",
+ "dotnet": "g.V().Values<object>(\"age\").Is(P.TypeOf(GType.List))",
+ "go": "g.V().Values(\"age\").Is(gremlingo.P.TypeOf(gremlingo.GType.List))",
+ "groovy": "g.V().values(\"age\").is(P.typeOf(GType.LIST))",
+ "java": "g.V().values(\"age\").is(P.typeOf(GType.LIST))",
+ "javascript": "g.V().values(\"age\").is(P.typeOf(GType.list))",
+ "python": "g.V().values('age').is_(P.type_of(GType.LIST))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlistX_isXtypeOfXGType_LISTXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"list\", [\"a\", \"b\", \"c\"])",
+ "language": "g.addV(\"data\").property(\"list\", [\"a\", \"b\", \"c\"])",
+ "anonymized": "g.addV(string0).property(string1, list0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"list\", new List<object> { \"a\", \"b\", \"c\" })",
+ "go": "g.AddV(\"data\").Property(\"list\", []interface{}{\"a\", \"b\", \"c\"})",
+ "groovy": "g.addV(\"data\").property(\"list\", [\"a\", \"b\", \"c\"])",
+ "java": "g.addV(\"data\").property(\"list\", new ArrayList<Object>() {{ add(\"a\"); add(\"b\"); add(\"c\"); }})",
+ "javascript": "g.addV(\"data\").property(\"list\", [\"a\", \"b\", \"c\"])",
+ "python": "g.add_v('data').property('list', ['a', 'b', 'c'])"
+ },
+ {
+ "original": "g.V().values(\"list\").is(P.typeOf(GType.LIST))",
+ "language": "g.V().values(\"list\").is(P.typeOf(GType.LIST))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LIST))",
+ "dotnet": "g.V().Values<object>(\"list\").Is(P.TypeOf(GType.List))",
+ "go": "g.V().Values(\"list\").Is(gremlingo.P.TypeOf(gremlingo.GType.List))",
+ "groovy": "g.V().values(\"list\").is(P.typeOf(GType.LIST))",
+ "java": "g.V().values(\"list\").is(P.typeOf(GType.LIST))",
+ "javascript": "g.V().values(\"list\").is(P.typeOf(GType.list))",
+ "python": "g.V().values('list').is_(P.type_of(GType.LIST))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXlist_typeOfXGType_LISTXX_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"name\", \"test\").property(\"list\", [1, 2, 3])",
+ "language": "g.addV(\"data\").property(\"name\", \"test\").property(\"list\", [1, 2, 3])",
+ "anonymized": "g.addV(string0).property(string1, string2).property(string3, list0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"name\", \"test\").Property(\"list\", new List<object> { 1, 2, 3 })",
+ "go": "g.AddV(\"data\").Property(\"name\", \"test\").Property(\"list\", []interface{}{1, 2, 3})",
+ "groovy": "g.addV(\"data\").property(\"name\", \"test\").property(\"list\", [1, 2, 3])",
+ "java": "g.addV(\"data\").property(\"name\", \"test\").property(\"list\", new ArrayList<Object>() {{ add(1); add(2); add(3); }})",
+ "javascript": "g.addV(\"data\").property(\"name\", \"test\").property(\"list\", [1, 2, 3])",
+ "python": "g.add_v('data').property('name', 'test').property('list', [1, 2, 3])"
+ },
+ {
+ "original": "g.V().has(\"list\", P.typeOf(GType.LIST)).values(\"name\")",
+ "language": "g.V().has(\"list\", P.typeOf(GType.LIST)).values(\"name\")",
+ "anonymized": "g.V().has(string0, P.typeOf(GType.LIST)).values(string1)",
+ "dotnet": "g.V().Has(\"list\", P.TypeOf(GType.List)).Values<object>(\"name\")",
+ "go": "g.V().Has(\"list\", gremlingo.P.TypeOf(gremlingo.GType.List)).Values(\"name\")",
+ "groovy": "g.V().has(\"list\", P.typeOf(GType.LIST)).values(\"name\")",
+ "java": "g.V().has(\"list\", P.typeOf(GType.LIST)).values(\"name\")",
+ "javascript": "g.V().has(\"list\", P.typeOf(GType.list)).values(\"name\")",
+ "python": "g.V().has('list', P.type_of(GType.LIST)).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlistX_isXtypeOfXGType_LISTXX_unfold",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"list\", [\"x\", \"y\", \"z\"])",
+ "language": "g.addV(\"data\").property(\"list\", [\"x\", \"y\", \"z\"])",
+ "anonymized": "g.addV(string0).property(string1, list0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"list\", new List<object> { \"x\", \"y\", \"z\" })",
+ "go": "g.AddV(\"data\").Property(\"list\", []interface{}{\"x\", \"y\", \"z\"})",
+ "groovy": "g.addV(\"data\").property(\"list\", [\"x\", \"y\", \"z\"])",
+ "java": "g.addV(\"data\").property(\"list\", new ArrayList<Object>() {{ add(\"x\"); add(\"y\"); add(\"z\"); }})",
+ "javascript": "g.addV(\"data\").property(\"list\", [\"x\", \"y\", \"z\"])",
+ "python": "g.add_v('data').property('list', ['x', 'y', 'z'])"
+ },
+ {
+ "original": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold()",
+ "language": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LIST)).unfold()",
+ "dotnet": "g.V().Values<object>(\"list\").Is(P.TypeOf(GType.List)).Unfold<object>()",
+ "go": "g.V().Values(\"list\").Is(gremlingo.P.TypeOf(gremlingo.GType.List)).Unfold()",
+ "groovy": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold()",
+ "java": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold()",
+ "javascript": "g.V().values(\"list\").is(P.typeOf(GType.list)).unfold()",
+ "python": "g.V().values('list').is_(P.type_of(GType.LIST)).unfold()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlistX_isXtypeOfXGType_LISTXX_countXlocalX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"list\", [1, 2, 3, 4, 5])",
+ "language": "g.addV(\"data\").property(\"list\", [1, 2, 3, 4, 5])",
+ "anonymized": "g.addV(string0).property(string1, list0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"list\", new List<object> { 1, 2, 3, 4, 5 })",
+ "go": "g.AddV(\"data\").Property(\"list\", []interface{}{1, 2, 3, 4, 5})",
+ "groovy": "g.addV(\"data\").property(\"list\", [1, 2, 3, 4, 5])",
+ "java": "g.addV(\"data\").property(\"list\", new ArrayList<Object>() {{ add(1); add(2); add(3); add(4); add(5); }})",
+ "javascript": "g.addV(\"data\").property(\"list\", [1, 2, 3, 4, 5])",
+ "python": "g.add_v('data').property('list', [1, 2, 3, 4, 5])"
+ },
+ {
+ "original": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).count(local)",
+ "language": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).count(Scope.local)",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LIST)).count(Scope.local)",
+ "dotnet": "g.V().Values<object>(\"list\").Is(P.TypeOf(GType.List)).Count(Scope.Local)",
+ "go": "g.V().Values(\"list\").Is(gremlingo.P.TypeOf(gremlingo.GType.List)).Count(gremlingo.Scope.Local)",
+ "groovy": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).count(Scope.local)",
+ "java": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).count(Scope.local)",
+ "javascript": "g.V().values(\"list\").is(P.typeOf(GType.list)).count(Scope.local)",
+ "python": "g.V().values('list').is_(P.type_of(GType.LIST)).count(Scope.local)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlistX_isXtypeOfXGType_LISTXX_unfold_rangeX1_3X",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"list\", [\"first\", \"second\", \"third\", \"fourth\"])",
+ "language": "g.addV(\"data\").property(\"list\", [\"first\", \"second\", \"third\", \"fourth\"])",
+ "anonymized": "g.addV(string0).property(string1, list0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"list\", new List<object> { \"first\", \"second\", \"third\", \"fourth\" })",
+ "go": "g.AddV(\"data\").Property(\"list\", []interface{}{\"first\", \"second\", \"third\", \"fourth\"})",
+ "groovy": "g.addV(\"data\").property(\"list\", [\"first\", \"second\", \"third\", \"fourth\"])",
+ "java": "g.addV(\"data\").property(\"list\", new ArrayList<Object>() {{ add(\"first\"); add(\"second\"); add(\"third\"); add(\"fourth\"); }})",
+ "javascript": "g.addV(\"data\").property(\"list\", [\"first\", \"second\", \"third\", \"fourth\"])",
+ "python": "g.add_v('data').property('list', ['first', 'second', 'third', 'fourth'])"
+ },
+ {
+ "original": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold().range(1, 3)",
+ "language": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold().range(1, 3)",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LIST)).unfold().range(number0, number1)",
+ "dotnet": "g.V().Values<object>(\"list\").Is(P.TypeOf(GType.List)).Unfold<object>().Range<object>(1, 3)",
+ "go": "g.V().Values(\"list\").Is(gremlingo.P.TypeOf(gremlingo.GType.List)).Unfold().Range(1, 3)",
+ "groovy": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold().range(1, 3)",
+ "java": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).unfold().range(1, 3)",
+ "javascript": "g.V().values(\"list\").is(P.typeOf(GType.list)).unfold().range(1, 3)",
+ "python": "g.V().values('list').is_(P.type_of(GType.LIST)).unfold().range_(1, 3)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlistX_isXtypeOfXGType_LISTXX_project_byXidentityX_byXcountXlocalX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"list\", [\"apple\", \"banana\"])",
+ "language": "g.addV(\"data\").property(\"list\", [\"apple\", \"banana\"])",
+ "anonymized": "g.addV(string0).property(string1, list0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"list\", new List<object> { \"apple\", \"banana\" })",
+ "go": "g.AddV(\"data\").Property(\"list\", []interface{}{\"apple\", \"banana\"})",
+ "groovy": "g.addV(\"data\").property(\"list\", [\"apple\", \"banana\"])",
+ "java": "g.addV(\"data\").property(\"list\", new ArrayList<Object>() {{ add(\"apple\"); add(\"banana\"); }})",
+ "javascript": "g.addV(\"data\").property(\"list\", [\"apple\", \"banana\"])",
+ "python": "g.add_v('data').property('list', ['apple', 'banana'])"
+ },
+ {
+ "original": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).project(\"original\", \"size\").by(identity()).by(count(local))",
+ "language": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).project(\"original\", \"size\").by(__.identity()).by(__.count(Scope.local))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LIST)).project(string1, string2).by(__.identity()).by(__.count(Scope.local))",
+ "dotnet": "g.V().Values<object>(\"list\").Is(P.TypeOf(GType.List)).Project<object>(\"original\", \"size\").By(__.Identity()).By(__.Count(Scope.Local))",
+ "go": "g.V().Values(\"list\").Is(gremlingo.P.TypeOf(gremlingo.GType.List)).Project(\"original\", \"size\").By(gremlingo.T__.Identity()).By(gremlingo.T__.Count(gremlingo.Scope.Local))",
+ "groovy": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).project(\"original\", \"size\").by(__.identity()).by(__.count(Scope.local))",
+ "java": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).project(\"original\", \"size\").by(__.identity()).by(__.count(Scope.local))",
+ "javascript": "g.V().values(\"list\").is(P.typeOf(GType.list)).project(\"original\", \"size\").by(__.identity()).by(__.count(Scope.local))",
+ "python": "g.V().values('list').is_(P.type_of(GType.LIST)).project('original', 'size').by(__.identity()).by(__.count(Scope.local))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlistX_isXtypeOfXGType_LISTXX_whereXcountXlocalX_isXgtX2XXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"list\", [1]).addV(\"data\").property(\"list\", [1, 2, 3])",
+ "language": "g.addV(\"data\").property(\"list\", [1]).addV(\"data\").property(\"list\", [1, 2, 3])",
+ "anonymized": "g.addV(string0).property(string1, list0).addV(string0).property(string1, list1)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"list\", new List<object> { 1 }).AddV((string) \"data\").Property(\"list\", new List<object> { 1, 2, 3 })",
+ "go": "g.AddV(\"data\").Property(\"list\", []interface{}{1}).AddV(\"data\").Property(\"list\", []interface{}{1, 2, 3})",
+ "groovy": "g.addV(\"data\").property(\"list\", [1]).addV(\"data\").property(\"list\", [1, 2, 3])",
+ "java": "g.addV(\"data\").property(\"list\", new ArrayList<Object>() {{ add(1); }}).addV(\"data\").property(\"list\", new ArrayList<Object>() {{ add(1); add(2); add(3); }})",
+ "javascript": "g.addV(\"data\").property(\"list\", [1]).addV(\"data\").property(\"list\", [1, 2, 3])",
+ "python": "g.add_v('data').property('list', [1]).add_v('data').property('list', [1, 2, 3])"
+ },
+ {
+ "original": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).where(count(local).is(P.gt(2)))",
+ "language": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).where(__.count(Scope.local).is(P.gt(2)))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LIST)).where(__.count(Scope.local).is(P.gt(number0)))",
+ "dotnet": "g.V().Values<object>(\"list\").Is(P.TypeOf(GType.List)).Where(__.Count(Scope.Local).Is(P.Gt(2)))",
+ "go": "g.V().Values(\"list\").Is(gremlingo.P.TypeOf(gremlingo.GType.List)).Where(gremlingo.T__.Count(gremlingo.Scope.Local).Is(gremlingo.P.Gt(2)))",
+ "groovy": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).where(__.count(Scope.local).is(P.gt(2)))",
+ "java": "g.V().values(\"list\").is(P.typeOf(GType.LIST)).where(__.count(Scope.local).is(P.gt(2)))",
+ "javascript": "g.V().values(\"list\").is(P.typeOf(GType.list)).where(__.count(Scope.local).is(P.gt(2)))",
+ "python": "g.V().values('list').is_(P.type_of(GType.LIST)).where(__.count(Scope.local).is_(P.gt(2)))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_injectXlistX_isXtypeOfXGType_LISTXX_groupCount",
+ "traversals": [
+ {
+ "original": "g.inject([\"test\"]).is(P.typeOf(GType.LIST)).groupCount()",
+ "language": "g.inject([\"test\"]).is(P.typeOf(GType.LIST)).groupCount()",
+ "anonymized": "g.inject(list0).is(P.typeOf(GType.LIST)).groupCount()",
+ "dotnet": "g.Inject<object>(new List<object> { \"test\" }).Is(P.TypeOf(GType.List)).GroupCount<object>()",
+ "go": "g.Inject([]interface{}{\"test\"}).Is(gremlingo.P.TypeOf(gremlingo.GType.List)).GroupCount()",
+ "groovy": "g.inject([\"test\"]).is(P.typeOf(GType.LIST)).groupCount()",
+ "java": "g.inject(new ArrayList<Object>() {{ add(\"test\"); }}).is(P.typeOf(GType.LIST)).groupCount()",
+ "javascript": "g.inject([\"test\"]).is(P.typeOf(GType.list)).groupCount()",
+ "python": "g.inject(['test']).is_(P.type_of(GType.LIST)).group_count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlongX_isXtypeOfXGType_LONGXX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"long\", 1L)",
+ "language": "g.addV(\"data\").property(\"long\", 1l)",
+ "anonymized": "g.addV(string0).property(string1, long0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"long\", 1l)",
+ "go": "g.AddV(\"data\").Property(\"long\", int64(1))",
+ "groovy": "g.addV(\"data\").property(\"long\", 1l)",
+ "java": "g.addV(\"data\").property(\"long\", 1l)",
+ "javascript": "g.addV(\"data\").property(\"long\", 1)",
+ "python": "g.add_v('data').property('long', long(1))"
+ },
+ {
+ "original": "g.V().values(\"long\").is(P.typeOf(GType.LONG))",
+ "language": "g.V().values(\"long\").is(P.typeOf(GType.LONG))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LONG))",
+ "dotnet": "g.V().Values<object>(\"long\").Is(P.TypeOf(GType.Long))",
+ "go": "g.V().Values(\"long\").Is(gremlingo.P.TypeOf(gremlingo.GType.Long))",
+ "groovy": "g.V().values(\"long\").is(P.typeOf(GType.LONG))",
+ "java": "g.V().values(\"long\").is(P.typeOf(GType.LONG))",
+ "javascript": "g.V().values(\"long\").is(P.typeOf(GType.long))",
+ "python": "g.V().values('long').is_(P.type_of(GType.LONG))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasXlong_typeOfXGType_LONGXX_valuesXnameX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"name\", \"test\").property(\"long\", 1L)",
+ "language": "g.addV(\"data\").property(\"name\", \"test\").property(\"long\", 1l)",
+ "anonymized": "g.addV(string0).property(string1, string2).property(string3, long0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"name\", \"test\").Property(\"long\", 1l)",
+ "go": "g.AddV(\"data\").Property(\"name\", \"test\").Property(\"long\", int64(1))",
+ "groovy": "g.addV(\"data\").property(\"name\", \"test\").property(\"long\", 1l)",
+ "java": "g.addV(\"data\").property(\"name\", \"test\").property(\"long\", 1l)",
+ "javascript": "g.addV(\"data\").property(\"name\", \"test\").property(\"long\", 1)",
+ "python": "g.add_v('data').property('name', 'test').property('long', long(1))"
+ },
+ {
+ "original": "g.V().has(\"long\", P.typeOf(GType.LONG)).values(\"name\")",
+ "language": "g.V().has(\"long\", P.typeOf(GType.LONG)).values(\"name\")",
+ "anonymized": "g.V().has(string0, P.typeOf(GType.LONG)).values(string1)",
+ "dotnet": "g.V().Has(\"long\", P.TypeOf(GType.Long)).Values<object>(\"name\")",
+ "go": "g.V().Has(\"long\", gremlingo.P.TypeOf(gremlingo.GType.Long)).Values(\"name\")",
+ "groovy": "g.V().has(\"long\", P.typeOf(GType.LONG)).values(\"name\")",
+ "java": "g.V().has(\"long\", P.typeOf(GType.LONG)).values(\"name\")",
+ "javascript": "g.V().has(\"long\", P.typeOf(GType.long)).values(\"name\")",
+ "python": "g.V().has('long', P.type_of(GType.LONG)).values('name')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlongX_isXtypeOfXGType_LONGXX_mathXmulX2XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"long\", 5L)",
+ "language": "g.addV(\"data\").property(\"long\", 5l)",
+ "anonymized": "g.addV(string0).property(string1, long0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"long\", 5l)",
+ "go": "g.AddV(\"data\").Property(\"long\", int64(5))",
+ "groovy": "g.addV(\"data\").property(\"long\", 5l)",
+ "java": "g.addV(\"data\").property(\"long\", 5l)",
+ "javascript": "g.addV(\"data\").property(\"long\", 5)",
+ "python": "g.add_v('data').property('long', long(5))"
+ },
+ {
+ "original": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).math(\"_ * 2\")",
+ "language": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).math(\"_ * 2\")",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LONG)).math(string1)",
+ "dotnet": "g.V().Values<object>(\"long\").Is(P.TypeOf(GType.Long)).Math(\"_ * 2\")",
+ "go": "g.V().Values(\"long\").Is(gremlingo.P.TypeOf(gremlingo.GType.Long)).Math(\"_ * 2\")",
+ "groovy": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).math(\"_ * 2\")",
+ "java": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).math(\"_ * 2\")",
+ "javascript": "g.V().values(\"long\").is(P.typeOf(GType.long)).math(\"_ * 2\")",
+ "python": "g.V().values('long').is_(P.type_of(GType.LONG)).math('_ * 2')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlongX_isXtypeOfXGType_LONGXX_isXgtX5XX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"long\", 10L)",
+ "language": "g.addV(\"data\").property(\"long\", 10l)",
+ "anonymized": "g.addV(string0).property(string1, long0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"long\", 10l)",
+ "go": "g.AddV(\"data\").Property(\"long\", int64(10))",
+ "groovy": "g.addV(\"data\").property(\"long\", 10l)",
+ "java": "g.addV(\"data\").property(\"long\", 10l)",
+ "javascript": "g.addV(\"data\").property(\"long\", 10)",
+ "python": "g.add_v('data').property('long', long(10))"
+ },
+ {
+ "original": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).is(P.gt(5L))",
+ "language": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).is(P.gt(5l))",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LONG)).is(P.gt(long0))",
+ "dotnet": "g.V().Values<object>(\"long\").Is(P.TypeOf(GType.Long)).Is(P.Gt(5l))",
+ "go": "g.V().Values(\"long\").Is(gremlingo.P.TypeOf(gremlingo.GType.Long)).Is(gremlingo.P.Gt(int64(5)))",
+ "groovy": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).is(P.gt(5l))",
+ "java": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).is(P.gt(5l))",
+ "javascript": "g.V().values(\"long\").is(P.typeOf(GType.long)).is(P.gt(5))",
+ "python": "g.V().values('long').is_(P.type_of(GType.LONG)).is_(P.gt(long(5)))"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlongX_isXtypeOfXGType_LONGXX_sumX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"long\", 1L).addV(\"data\").property(\"long\", 2L).addV(\"data\").property(\"long\", 3L)",
+ "language": "g.addV(\"data\").property(\"long\", 1l).addV(\"data\").property(\"long\", 2l).addV(\"data\").property(\"long\", 3l)",
+ "anonymized": "g.addV(string0).property(string1, long0).addV(string0).property(string1, long1).addV(string0).property(string1, long2)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"long\", 1l).AddV((string) \"data\").Property(\"long\", 2l).AddV((string) \"data\").Property(\"long\", 3l)",
+ "go": "g.AddV(\"data\").Property(\"long\", int64(1)).AddV(\"data\").Property(\"long\", int64(2)).AddV(\"data\").Property(\"long\", int64(3))",
+ "groovy": "g.addV(\"data\").property(\"long\", 1l).addV(\"data\").property(\"long\", 2l).addV(\"data\").property(\"long\", 3l)",
+ "java": "g.addV(\"data\").property(\"long\", 1l).addV(\"data\").property(\"long\", 2l).addV(\"data\").property(\"long\", 3l)",
+ "javascript": "g.addV(\"data\").property(\"long\", 1).addV(\"data\").property(\"long\", 2).addV(\"data\").property(\"long\", 3)",
+ "python": "g.add_v('data').property('long', long(1)).add_v('data').property('long', long(2)).add_v('data').property('long', long(3))"
+ },
+ {
+ "original": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).sum()",
+ "language": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).sum()",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LONG)).sum()",
+ "dotnet": "g.V().Values<object>(\"long\").Is(P.TypeOf(GType.Long)).Sum<object>()",
+ "go": "g.V().Values(\"long\").Is(gremlingo.P.TypeOf(gremlingo.GType.Long)).Sum()",
+ "groovy": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).sum()",
+ "java": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).sum()",
+ "javascript": "g.V().values(\"long\").is(P.typeOf(GType.long)).sum()",
+ "python": "g.V().values('long').is_(P.type_of(GType.LONG)).sum_()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_valuesXlongX_isXtypeOfXGType_LONGXX_localXaggregateXaXX_capXaX",
+ "traversals": [
+ {
+ "original": "g.addV(\"data\").property(\"long\", 100L)",
+ "language": "g.addV(\"data\").property(\"long\", 100l)",
+ "anonymized": "g.addV(string0).property(string1, long0)",
+ "dotnet": "g.AddV((string) \"data\").Property(\"long\", 100l)",
+ "go": "g.AddV(\"data\").Property(\"long\", int64(100))",
+ "groovy": "g.addV(\"data\").property(\"long\", 100l)",
+ "java": "g.addV(\"data\").property(\"long\", 100l)",
+ "javascript": "g.addV(\"data\").property(\"long\", 100)",
+ "python": "g.add_v('data').property('long', long(100))"
+ },
+ {
+ "original": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).local(aggregate(\"a\")).cap(\"a\")",
+ "language": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "anonymized": "g.V().values(string0).is(P.typeOf(GType.LONG)).local(__.aggregate(string1)).cap(string1)",
+ "dotnet": "g.V().Values<object>(\"long\").Is(P.TypeOf(GType.Long)).Local<object>(__.Aggregate(\"a\")).Cap<object>(\"a\")",
+ "go": "g.V().Values(\"long\").Is(gremlingo.P.TypeOf(gremlingo.GType.Long)).Local(gremlingo.T__.Aggregate(\"a\")).Cap(\"a\")",
+ "groovy": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "java": "g.V().values(\"long\").is(P.typeOf(GType.LONG)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "javascript": "g.V().values(\"long\").is(P.typeOf(GType.long)).local(__.aggregate(\"a\")).cap(\"a\")",
+ "python": "g.V().values('long').is_(P.type_of(GType.LONG)).local(__.aggregate('a')).cap('a')"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_hasLabelXpersonX_valueMap_isXtypeOfXGType_MAPXX_count",
+ "traversals": [
+ {
+ "original": "g.V().hasLabel(\"person\").valueMap().is(P.typeOf(GType.MAP)).count()",
+ "language": "g.V().hasLabel(\"person\").valueMap().is(P.typeOf(GType.MAP)).count()",
+ "anonymized": "g.V().hasLabel(string0).valueMap().is(P.typeOf(GType.MAP)).count()",
+ "dotnet": "g.V().HasLabel(\"person\").ValueMap<object, object>().Is(P.TypeOf(GType.Map)).Count()",
+ "go": "g.V().HasLabel(\"person\").ValueMap().Is(gremlingo.P.TypeOf(gremlingo.GType.Map)).Count()",
+ "groovy": "g.V().hasLabel(\"person\").valueMap().is(P.typeOf(GType.MAP)).count()",
+ "java": "g.V().hasLabel(\"person\").valueMap().is(P.typeOf(GType.MAP)).count()",
+ "javascript": "g.V().hasLabel(\"person\").valueMap().is(P.typeOf(GType.map)).count()",
+ "python": "g.V().has_label('person').value_map().is_(P.type_of(GType.MAP)).count()"
+ }
+ ]
+ },
+ {
+ "scenario": "g_V_groupCount_byXlabelX_isXtypeOfXGType_MAPX",
+ "traversals": [
+ {
+ "original": "g.V().groupCount().by(label).is(P.typeOf(GType.MAP))",
+ "language": "g.V().groupCount().by(T.label).is(P.typeOf(GType.MAP))",
+ "anonymized": "g.V().groupCount().by(T.label).is(P.typeOf(GType.MAP))",
+ "dotnet": "g.V().GroupCount<object>().By(T.Label).Is(P.TypeOf(GType.Map))",
+ "go": "g.V().GroupCount().By(gremlingo.T.Label).Is(gremlingo.P.TypeOf(gremlingo.GType.Map))",
+ "groovy": "g.V().groupCount().by(T.label).is(P.typeOf(GType.MAP))",
+ "java": "g.V().groupCount().by(T.label).is(P.typeOf(GType.MAP))",
... 36723 lines suppressed ...
(tinkerpop) 02/03: Added translator tool to gremlin-mcp
Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch js-translator
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 76f4fa937e85fb2a1c509b1cf91f97bbe7c5194e
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Tue Mar 10 09:01:04 2026 -0400
Added translator tool to gremlin-mcp
The translator only converts canonical Gremlin to variants.
---
.../javascript/gremlin-javascript/package.json | 8 +-
gremlin-mcp/src/main/javascript/package.json | 4 +-
.../main/javascript/scripts/generate-step-names.js | 99 +++++++
gremlin-mcp/src/main/javascript/src/config.ts | 31 +--
.../src/main/javascript/src/connectivity-state.ts | 68 +++++
gremlin-mcp/src/main/javascript/src/constants.ts | 1 +
.../src/main/javascript/src/gremlin/client.ts | 31 +--
.../src/main/javascript/src/gremlin/connection.ts | 231 +++++++++-------
.../src/main/javascript/src/gremlin/query-utils.ts | 15 +-
.../javascript/src/gremlin/schema-generator.ts | 8 +-
.../src/main/javascript/src/gremlin/schema.ts | 17 +-
.../src/main/javascript/src/gremlin/service.ts | 119 +++++---
.../src/main/javascript/src/gremlin/types.ts | 2 +-
.../src/main/javascript/src/handlers/resources.ts | 84 ++++--
.../src/main/javascript/src/handlers/tools.ts | 248 +++++++++++++++--
gremlin-mcp/src/main/javascript/src/server.ts | 218 ++++++++++-----
.../src/main/javascript/src/translator/index.ts | 72 +++++
.../src/main/javascript/src/translator/llm.ts | 66 +++++
.../src/translator/normalizers/shared.ts | 69 +++++
.../main/javascript/src/translator/stepNames.ts | 305 +++++++++++++++++++++
.../src/main/javascript/tests/config.test.ts | 33 ++-
.../tests/resource-read.integration.test.ts | 145 ++++++++++
.../src/main/javascript/tests/resources.test.ts | 133 +++++++++
.../gremlin/language/translator/translations.json | 251 ++++++++++++++++-
24 files changed, 1944 insertions(+), 314 deletions(-)
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json
index 74256e8e25..bbe04bd3ac 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json
@@ -25,7 +25,13 @@
"require": "./build/cjs/index.cjs"
},
"./language": {
- "import": "./build/esm/language/index.js"
+ "import": "./build/esm/language/index.js",
+ "types": "./build/esm/language/index.d.ts"
+ }
+ },
+ "typesVersions": {
+ "*": {
+ "language": ["./build/esm/language/index.d.ts"]
}
},
"files": [
diff --git a/gremlin-mcp/src/main/javascript/package.json b/gremlin-mcp/src/main/javascript/package.json
index 709bc9d62d..80125e30c1 100644
--- a/gremlin-mcp/src/main/javascript/package.json
+++ b/gremlin-mcp/src/main/javascript/package.json
@@ -8,7 +8,8 @@
"gremlin-mcp": "dist/server.js"
},
"scripts": {
- "build": "tsc && chmod +x dist/server.js",
+ "generate-step-names": "node scripts/generate-step-names.js",
+ "build": "npm run generate-step-names && tsc && chmod +x dist/server.js",
"dev": "tsx src/server.ts",
"start": "node dist/server.js",
"test": "jest",
@@ -49,6 +50,7 @@
"@types/gremlin": "^3.6.7",
"effect": "^3.17.9",
"gremlin": "^3.7.4",
+ "gremlin-language": "file:../../../../gremlin-javascript/src/main/javascript/gremlin-javascript",
"winston": "^3.17.0",
"zod": "^3.25.76"
},
diff --git a/gremlin-mcp/src/main/javascript/scripts/generate-step-names.js b/gremlin-mcp/src/main/javascript/scripts/generate-step-names.js
new file mode 100644
index 0000000000..eca91f6c24
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/scripts/generate-step-names.js
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Generates src/translator/stepNames.ts from the Gremlin.g4 grammar.
+ *
+ * Extracts all traversalMethod_xxx and traversalSourceSpawnMethod_xxx rule names,
+ * derives camelCase canonical step names and their PascalCase equivalents used by
+ * Go and .NET dialects.
+ *
+ * Run via: npm run generate-step-names
+ */
+
+import { readFileSync, writeFileSync } from 'fs';
+import { join, dirname } from 'path';
+import { fileURLToPath } from 'url';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+
+const grammarPath = join(
+ __dirname,
+ '../../../../../gremlin-language/src/main/antlr4/Gremlin.g4'
+);
+const outputPath = join(__dirname, '../src/translator/stepNames.ts');
+
+const grammar = readFileSync(grammarPath, 'utf-8');
+
+const stepNames = new Set();
+for (const line of grammar.split('\n')) {
+ const match = line.match(/^traversal(?:Method|SourceSpawnMethod)_([a-zA-Z]+)/);
+ if (match) {
+ stepNames.add(match[1]);
+ }
+}
+
+const sorted = [...stepNames].sort();
+
+const camelCaseEntries = sorted.map(n => ` '${n}',`).join('\n');
+const pascalCaseEntries = sorted
+ .map(n => ` '${n[0].toUpperCase()}${n.slice(1)}',`)
+ .join('\n');
+
+const content = `/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Generated by scripts/generate-step-names.js — do not edit manually.
+// Re-run \`npm run generate-step-names\` after changes to Gremlin.g4.
+
+/**
+ * Canonical camelCase Gremlin step names derived from the gremlin-language grammar.
+ * Used to safely identify step names during normalization.
+ */
+export const GREMLIN_STEP_NAMES: ReadonlySet<string> = new Set([
+${camelCaseEntries}
+]);
+
+/**
+ * PascalCase equivalents of Gremlin step names, as used by Go and .NET dialects.
+ * Used as an allowlist when converting PascalCase tokens to camelCase during normalization.
+ */
+export const GREMLIN_STEP_NAMES_PASCAL: ReadonlySet<string> = new Set([
+${pascalCaseEntries}
+]);
+`;
+
+writeFileSync(outputPath, content, 'utf-8');
+console.log(`Generated ${outputPath} with ${stepNames.size} step names.`);
diff --git a/gremlin-mcp/src/main/javascript/src/config.ts b/gremlin-mcp/src/main/javascript/src/config.ts
index 1a9b3b9395..ced9b09d7b 100644
--- a/gremlin-mcp/src/main/javascript/src/config.ts
+++ b/gremlin-mcp/src/main/javascript/src/config.ts
@@ -110,11 +110,12 @@ const parseCommaSeparatedList = (value: string): string[] =>
.filter(s => s.length > 0);
/**
- * GREMLIN_MCP_ENDPOINT: string, required. Gremlin Server compatible websocket endpoint.
+ * GREMLIN_MCP_ENDPOINT: string, optional. Gremlin Server compatible websocket endpoint.
+ * When omitted the server starts in offline mode — translate/format tools remain available
+ * but graph tools (query, schema, status) will return a "no server configured" error.
*/
-const GremlinMcpEndpointConfig = pipe(
- Config.string('GREMLIN_MCP_ENDPOINT'),
- Config.mapOrFail(parseEndpoint)
+const GremlinMcpEndpointConfig = Config.option(
+ pipe(Config.string('GREMLIN_MCP_ENDPOINT'), Config.mapOrFail(parseEndpoint))
);
/**
@@ -218,21 +219,13 @@ const GremlinMcpSchemaIncludeCountsConfig = Config.withDefault(
* Ensures host, port, traversalSource, useSSL, username, password, and idleTimeout are present and valid.
* Returns a validated config object or throws ConfigError on failure.
*/
-const ConnectionConfig = pipe(
- Config.all({
- endpoint: GremlinMcpEndpointConfig,
- useSSL: GremlinMcpUseSslConfig,
- username: GremlinMcpUsernameConfig,
- password: GremlinMcpPasswordConfig,
- idleTimeout: GremlinMcpIdleTimeoutConfig,
- }),
- Config.map(({ endpoint, ...rest }) => ({
- host: endpoint.host,
- port: endpoint.port,
- traversalSource: endpoint.traversalSource,
- ...rest,
- }))
-);
+const ConnectionConfig = Config.all({
+ endpoint: GremlinMcpEndpointConfig,
+ useSSL: GremlinMcpUseSslConfig,
+ username: GremlinMcpUsernameConfig,
+ password: GremlinMcpPasswordConfig,
+ idleTimeout: GremlinMcpIdleTimeoutConfig,
+});
/**
* SchemaDiscoveryConfig: Aggregates and validates all schema discovery-related environment variables.
diff --git a/gremlin-mcp/src/main/javascript/src/connectivity-state.ts b/gremlin-mcp/src/main/javascript/src/connectivity-state.ts
new file mode 100644
index 0000000000..22e72a1d4e
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/src/connectivity-state.ts
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import type { GremlinConnectionError } from './errors.js';
+
+export type GremlinConnectivityState = 'unknown' | 'connected' | 'disconnected';
+
+type ConnectivityListener = (
+ next: GremlinConnectivityState,
+ previous: GremlinConnectivityState
+) => void;
+
+let connectivityState: GremlinConnectivityState = 'unknown';
+const listeners = new Set<ConnectivityListener>();
+
+const transitionConnectivityState = (next: GremlinConnectivityState): void => {
+ const previous = connectivityState;
+ if (previous === next) {
+ return;
+ }
+ connectivityState = next;
+ for (const listener of listeners) {
+ listener(next, previous);
+ }
+};
+
+export const markGremlinConnected = (): void => {
+ transitionConnectivityState('connected');
+};
+
+export const markGremlinDisconnected = (): void => {
+ transitionConnectivityState('disconnected');
+};
+
+export const getGremlinConnectivityState = (): GremlinConnectivityState => connectivityState;
+
+export const onGremlinConnectivityStateChange = (listener: ConnectivityListener): (() => void) => {
+ listeners.add(listener);
+ return () => listeners.delete(listener);
+};
+
+export const isGremlinConnectionError = (error: unknown): error is GremlinConnectionError =>
+ typeof error === 'object' &&
+ error !== null &&
+ '_tag' in error &&
+ (error as { _tag?: string })._tag === 'GremlinConnectionError';
+
+// Test-only utility to reset global singleton state between test cases.
+export const resetGremlinConnectivityStateForTests = (): void => {
+ connectivityState = 'unknown';
+ listeners.clear();
+};
diff --git a/gremlin-mcp/src/main/javascript/src/constants.ts b/gremlin-mcp/src/main/javascript/src/constants.ts
index eeee0796a1..8a71ca496e 100644
--- a/gremlin-mcp/src/main/javascript/src/constants.ts
+++ b/gremlin-mcp/src/main/javascript/src/constants.ts
@@ -45,6 +45,7 @@ export const TOOL_NAMES = {
RUN_GREMLIN_QUERY: 'run_gremlin_query',
REFRESH_SCHEMA_CACHE: 'refresh_schema_cache',
FORMAT_GREMLIN_QUERY: 'format_gremlin_query',
+ TRANSLATE_GREMLIN_QUERY: 'translate_gremlin_query',
} as const;
// Default Configuration Values
diff --git a/gremlin-mcp/src/main/javascript/src/gremlin/client.ts b/gremlin-mcp/src/main/javascript/src/gremlin/client.ts
index 83563d38c9..4c5392d2f4 100644
--- a/gremlin-mcp/src/main/javascript/src/gremlin/client.ts
+++ b/gremlin-mcp/src/main/javascript/src/gremlin/client.ts
@@ -17,25 +17,24 @@
* under the License.
*/
-import { Context } from 'effect';
+import { Context, Effect } from 'effect';
+import type { GremlinConnectionError } from '../errors.js';
import type { ConnectionState } from './types.js';
/**
- * Represents the Gremlin client as a service in the Effect context.
+ * Gremlin client service providing lazy, reconnect-capable connection management.
*
- * This service provides access to the active Gremlin connection state,
- * including the client, connection, and traversal source (`g`).
+ * `getConnection` returns the existing connection from the cache, or creates a new
+ * one if none exists. Fails with `GremlinConnectionError` if no endpoint is configured
+ * or if the connection attempt fails.
*
- * @example
- * ```typescript
- * import { Effect } from 'effect';
- * import { GremlinClient } from './client.js';
- *
- * const myEffect = Effect.gen(function* () {
- * const gremlin = yield* GremlinClient;
- * const count = yield* Effect.tryPromise(() => gremlin.g.V().count().next());
- * return count.value;
- * });
- * ```
+ * `invalidate` closes the current connection (if any) and clears the cache so the
+ * next `getConnection` call creates a fresh connection.
*/
-export class GremlinClient extends Context.Tag('GremlinClient')<GremlinClient, ConnectionState>() {}
+export class GremlinClient extends Context.Tag('GremlinClient')<
+ GremlinClient,
+ {
+ readonly getConnection: Effect.Effect<ConnectionState, GremlinConnectionError>;
+ readonly invalidate: Effect.Effect<void, never>;
+ }
+>() {}
diff --git a/gremlin-mcp/src/main/javascript/src/gremlin/connection.ts b/gremlin-mcp/src/main/javascript/src/gremlin/connection.ts
index a85fbf3362..4f2b710e4c 100644
--- a/gremlin-mcp/src/main/javascript/src/gremlin/connection.ts
+++ b/gremlin-mcp/src/main/javascript/src/gremlin/connection.ts
@@ -20,128 +20,171 @@
/**
* @fileoverview Provides a live implementation of the GremlinClient service.
*
- * This module defines the `GremlinClientLive` layer, which is responsible for
- * creating and managing the lifecycle of a Gremlin database connection.
- * The layer uses `Effect.Layer` to provide the `GremlinClient` service
- * to the application's context, ensuring that the connection is acquired
- * when the layer is built and released when the application shuts down.
+ * At layer construction time, checks whether GREMLIN_MCP_ENDPOINT is configured:
+ *
+ * - **Offline mode** (no endpoint): `getConnection` always fails immediately with a
+ * clear error. No gremlin driver objects (Client, DriverRemoteConnection, etc.)
+ * are ever instantiated.
+ *
+ * - **Online mode** (endpoint configured): connection is created lazily on first use
+ * and cached. On invalidation the connection is closed and the cache cleared, so
+ * the next `getConnection` creates a fresh connection.
*/
-import { Effect, Layer, Option, Redacted } from 'effect';
+import { Effect, Layer, Option, Redacted, Ref, pipe } from 'effect';
import gremlin from 'gremlin';
import { AppConfig } from '../config.js';
import { Errors } from '../errors.js';
import { GremlinClient } from './client.js';
import type { ConnectionState } from './types.js';
+import type { GremlinConnectionError } from '../errors.js';
const { PlainTextSaslAuthenticator } = gremlin.driver.auth;
const { Client, DriverRemoteConnection } = gremlin.driver;
const { AnonymousTraversalSource } = gremlin.process;
+const NO_ENDPOINT_MSG =
+ 'No Gremlin Server configured. Set GREMLIN_MCP_ENDPOINT to enable graph operations.';
+
/**
- * Creates and tests a Gremlin connection.
- *
- * This effect is responsible for establishing a connection to the Gremlin
- * server, creating a client and a graph traversal source (`g`), and then
- * testing the connection to ensure it is functional before it is used.
- *
- * @param config The application configuration containing Gremlin connection details.
- * @returns An `Effect` that resolves to a `ConnectionState` object or fails with a `GremlinConnectionError`.
+ * Safely closes a Gremlin connection, logging any errors without propagating them.
*/
-const makeConnection = Effect.gen(function* () {
- const config = yield* AppConfig;
- const protocol = config.gremlin.useSSL ? 'wss' : 'ws';
- const url = `${protocol}://${config.gremlin.host}:${config.gremlin.port}/gremlin`;
- const traversalSource = config.gremlin.traversalSource;
-
- yield* Effect.logInfo('Acquiring Gremlin connection', {
- host: config.gremlin.host,
- port: config.gremlin.port,
- ssl: config.gremlin.useSSL,
- traversalSource: config.gremlin.traversalSource,
- });
-
- const auth = Option.zipWith(
- config.gremlin.username,
- config.gremlin.password,
- (username, password) => ({ username, password: Redacted.value(password) })
- );
-
- // Build a proper Gremlin authenticator when credentials are provided
- const authenticator = Option.map(
- auth,
- ({ username, password }) => new PlainTextSaslAuthenticator(username, password)
- );
-
- const connection = yield* Effect.try({
- try: () =>
- new DriverRemoteConnection(url, {
- traversalSource,
- authenticator: Option.getOrUndefined(authenticator),
+const closeConnection = (state: ConnectionState): Effect.Effect<void, never> =>
+ Effect.gen(function* () {
+ yield* Effect.logInfo('Closing Gremlin connection');
+ yield* pipe(
+ Effect.tryPromise({
+ try: () => state.connection.close(),
+ catch: error => Errors.connection('Failed to close Gremlin connection', { error }),
}),
- catch: error => Errors.connection('Failed to create remote connection', { error }),
+ Effect.catchAll(error => Effect.logWarning(`Error during connection close: ${error.message}`))
+ );
+ yield* Effect.logInfo('Gremlin connection closed');
});
- const g = AnonymousTraversalSource.traversal().withRemote(connection);
- const client = new Client(url, {
- traversalSource,
- authenticator: Option.getOrUndefined(authenticator),
- });
+/**
+ * Creates a fresh Gremlin connection. Only called when the endpoint IS configured.
+ */
+const createConnection = (
+ host: string,
+ port: number,
+ traversalSource: string,
+ useSSL: boolean,
+ authenticatorInput: Option.Option<{ username: string; password: string }>
+): Effect.Effect<ConnectionState, GremlinConnectionError> =>
+ Effect.gen(function* () {
+ const protocol = useSSL ? 'wss' : 'ws';
+ const url = `${protocol}://${host}:${port}/gremlin`;
- // Test the connection
- yield* Effect.tryPromise({
- try: () => g.inject(1).next(),
- catch: error => Errors.connection('Connection test failed', { error }),
- });
+ yield* Effect.logInfo('Creating Gremlin connection', {
+ host,
+ port,
+ ssl: useSSL,
+ traversalSource,
+ });
- yield* Effect.logInfo('✅ Gremlin connection acquired successfully');
+ const authenticator = Option.map(
+ authenticatorInput,
+ ({ username, password }) => new PlainTextSaslAuthenticator(username, password)
+ );
- return {
- client,
- connection,
- g,
- lastUsed: Date.now(),
- };
-});
+ const connection = yield* Effect.try({
+ try: () =>
+ new DriverRemoteConnection(url, {
+ traversalSource,
+ authenticator: Option.getOrUndefined(authenticator),
+ }),
+ catch: error => Errors.connection('Failed to create remote connection', { error }),
+ });
-/**
- * Safely closes a Gremlin connection.
- *
- * This effect takes a `ConnectionState` and closes the underlying connection,
- * logging any errors that occur during the process.
- *
- * @param state The `ConnectionState` to be closed.
- * @returns An `Effect` that completes when the connection is closed.
- */
-const releaseConnection = (state: ConnectionState) =>
- Effect.gen(function* () {
- yield* Effect.logInfo('Releasing Gremlin connection');
+ const g = AnonymousTraversalSource.traversal().withRemote(connection);
+ const client = new Client(url, {
+ traversalSource,
+ authenticator: Option.getOrUndefined(authenticator),
+ });
+
+ // Verify the server is reachable before caching
yield* Effect.tryPromise({
- try: () => state.connection.close(),
- catch: error => Errors.connection('Failed to close Gremlin connection', { error }),
- }).pipe(Effect.catchAll(error => Effect.logWarning(`Error during release: ${error.message}`)));
- yield* Effect.logInfo('Gremlin connection released successfully');
+ try: () => g.inject(1).next(),
+ catch: error => Errors.connection('Connection test failed', { error }),
+ });
+
+ yield* Effect.logInfo('✅ Gremlin connection established and verified');
+
+ return { client, connection, g, lastUsed: Date.now() };
});
/**
* A layer that provides a live `GremlinClient` service.
*
- * This layer is responsible for the lifecycle of the Gremlin connection.
- * It acquires a connection when the layer is initialized and releases it
- * when the application scope is closed.
- *
- * @example
- * ```typescript
- * import { Effect } from 'effect';
- * import { GremlinClientLive } from './connection.js';
- *
- * const myApp = Effect.provide(
- * // my effects...
- * GremlinClientLive
- * );
- * ```
+ * Branches at construction time on whether GREMLIN_MCP_ENDPOINT is configured:
+ * - No endpoint → offline service; `getConnection` always fails, no driver objects created.
+ * - Endpoint set → online service; lazy cached connection with invalidate support.
*/
export const GremlinClientLive = Layer.scoped(
GremlinClient,
- Effect.acquireRelease(makeConnection, releaseConnection)
+ Effect.gen(function* () {
+ const config = yield* AppConfig;
+
+ // ── Offline mode ──────────────────────────────────────────────────────────
+ if (Option.isNone(config.gremlin.endpoint)) {
+ yield* Effect.logInfo(
+ '⚠️ No GREMLIN_MCP_ENDPOINT configured — starting in offline mode. ' +
+ 'Translate and format tools are available; graph tools require an endpoint.'
+ );
+ return GremlinClient.of({
+ getConnection: Effect.fail(Errors.connection(NO_ENDPOINT_MSG)),
+ invalidate: Effect.void,
+ });
+ }
+
+ // ── Online mode ───────────────────────────────────────────────────────────
+ const { host, port, traversalSource } = config.gremlin.endpoint.value;
+
+ const authenticatorInput = Option.zipWith(
+ config.gremlin.username,
+ config.gremlin.password,
+ (username, password) => ({ username, password: Redacted.value(password) })
+ );
+
+ const ref = yield* Ref.make<Option.Option<ConnectionState>>(Option.none());
+
+ // Release connection when the scope closes
+ yield* Effect.addFinalizer(() =>
+ Effect.gen(function* () {
+ const current = yield* Ref.get(ref);
+ if (Option.isSome(current)) {
+ yield* closeConnection(current.value);
+ }
+ })
+ );
+
+ const getConnection: Effect.Effect<ConnectionState, GremlinConnectionError> = Effect.gen(
+ function* () {
+ const current = yield* Ref.get(ref);
+ if (Option.isSome(current)) {
+ return current.value;
+ }
+ const state = yield* createConnection(
+ host,
+ port,
+ traversalSource,
+ config.gremlin.useSSL,
+ authenticatorInput
+ );
+ yield* Ref.set(ref, Option.some(state));
+ return state;
+ }
+ );
+
+ const invalidate: Effect.Effect<void, never> = Effect.gen(function* () {
+ const current = yield* Ref.get(ref);
+ yield* Ref.set(ref, Option.none());
+ if (Option.isSome(current)) {
+ yield* closeConnection(current.value);
+ }
+ });
+
+ return GremlinClient.of({ getConnection, invalidate });
+ })
);
diff --git a/gremlin-mcp/src/main/javascript/src/gremlin/query-utils.ts b/gremlin-mcp/src/main/javascript/src/gremlin/query-utils.ts
index 4ee5c9448f..aff8bd3fb4 100644
--- a/gremlin-mcp/src/main/javascript/src/gremlin/query-utils.ts
+++ b/gremlin-mcp/src/main/javascript/src/gremlin/query-utils.ts
@@ -33,6 +33,17 @@ type GraphTraversalSource = process.GraphTraversalSource;
const { label } = gremlin.process.statics;
+type CountResult = { value?: unknown };
+
+const extractCountMap = (result: unknown): Map<string, number> | undefined => {
+ if (typeof result !== 'object' || result === null || !('value' in result)) {
+ return undefined;
+ }
+
+ const value = (result as CountResult).value;
+ return value instanceof Map ? (value as Map<string, number>) : undefined;
+};
+
/**
* Processes items in controlled batches with concurrency limiting.
*
@@ -127,7 +138,7 @@ export const getVertexCountsPerLabel = (g: GraphTraversalSource) =>
'g.V().groupCount().by(label()).next()'
).pipe(
Effect.map(result => {
- const map = (result as any)?.value as Map<string, number> | undefined;
+ const map = extractCountMap(result);
return { value: map ? (Object.fromEntries(map) as Record<string, number>) : undefined };
})
);
@@ -145,7 +156,7 @@ export const getEdgeCountsPerLabel = (g: GraphTraversalSource) =>
'g.E().groupCount().by(label()).next()'
).pipe(
Effect.map(result => {
- const map = (result as any)?.value as Map<string, number> | undefined;
+ const map = extractCountMap(result);
return { value: map ? (Object.fromEntries(map) as Record<string, number>) : undefined };
})
);
diff --git a/gremlin-mcp/src/main/javascript/src/gremlin/schema-generator.ts b/gremlin-mcp/src/main/javascript/src/gremlin/schema-generator.ts
index aed0dc6656..98e74caf5a 100644
--- a/gremlin-mcp/src/main/javascript/src/gremlin/schema-generator.ts
+++ b/gremlin-mcp/src/main/javascript/src/gremlin/schema-generator.ts
@@ -27,7 +27,7 @@
import { Effect, Duration } from 'effect';
import { type GraphSchema, type Vertex, type Edge } from './models/index.js';
-import { Errors, type GremlinConnectionError, type GremlinQueryError } from '../errors.js';
+import { Errors, type GremlinQueryError } from '../errors.js';
import type { ConnectionState, SchemaConfig } from './types.js';
import {
getVertexLabels,
@@ -176,12 +176,8 @@ const applySchemaTimeout = (
export const generateGraphSchema = (
connectionState: ConnectionState,
config: SchemaConfig = DEFAULT_SCHEMA_CONFIG
-): Effect.Effect<GraphSchema, GremlinConnectionError | GremlinQueryError> =>
+): Effect.Effect<GraphSchema, GremlinQueryError> =>
Effect.gen(function* () {
- if (!connectionState.g) {
- return yield* Effect.fail(Errors.connection('Graph traversal source not available'));
- }
-
const g = connectionState.g;
const startTime = Date.now();
diff --git a/gremlin-mcp/src/main/javascript/src/gremlin/schema.ts b/gremlin-mcp/src/main/javascript/src/gremlin/schema.ts
index 5ac1528a75..373ad8a1e5 100644
--- a/gremlin-mcp/src/main/javascript/src/gremlin/schema.ts
+++ b/gremlin-mcp/src/main/javascript/src/gremlin/schema.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { Effect, Context, Layer } from 'effect';
+import { Effect, Context, Layer, pipe } from 'effect';
import { generateGraphSchema, DEFAULT_SCHEMA_CONFIG } from './schema-generator.js';
import {
createSchemaCache,
@@ -50,11 +50,16 @@ export const SchemaServiceLive = Layer.effect(
const config = yield* AppConfig;
const cacheRef = yield* createSchemaCache();
- const generateSchemaEffect = generateGraphSchema(gremlinClient, {
- ...DEFAULT_SCHEMA_CONFIG,
- includeCounts: config.schema.includeCounts,
- includeSampleValues: config.schema.includeSampleValues,
- });
+ const generateSchemaEffect = pipe(
+ gremlinClient.getConnection,
+ Effect.flatMap(conn =>
+ generateGraphSchema(conn, {
+ ...DEFAULT_SCHEMA_CONFIG,
+ includeCounts: config.schema.includeCounts,
+ includeSampleValues: config.schema.includeSampleValues,
+ })
+ )
+ );
const getSchema = getCachedSchema(cacheRef, generateSchemaEffect);
const peekSchema = peekCachedSchema(cacheRef);
diff --git a/gremlin-mcp/src/main/javascript/src/gremlin/service.ts b/gremlin-mcp/src/main/javascript/src/gremlin/service.ts
index 19e4cabc18..999c4900db 100644
--- a/gremlin-mcp/src/main/javascript/src/gremlin/service.ts
+++ b/gremlin-mcp/src/main/javascript/src/gremlin/service.ts
@@ -9,7 +9,7 @@
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
+ * Unless required by applicable law or agreed in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
@@ -22,7 +22,8 @@
*
* Provides a modular, composable service layer for Gremlin graph databases using
* Effect-ts patterns. Handles connection management, schema caching, query execution,
- * and error handling.
+ * and error handling. On any GremlinConnectionError the service invalidates the
+ * cached connection and retries the operation once to transparently reconnect.
*/
import { Effect, Context, Layer, pipe } from 'effect';
@@ -32,7 +33,7 @@ import { isGremlinResult } from '../utils/type-guards.js';
import { GremlinConnectionError, GremlinQueryError, Errors, ParseError } from '../errors.js';
import { GremlinClient } from './client.js';
import { SchemaService } from './schema.js';
-import type { GremlinClientType, GremlinResultSet } from './types.js';
+import type { GremlinClientType, GremlinResultSet, ConnectionState } from './types.js';
import type { GraphSchema, ServiceStatus } from './types.js';
/**
@@ -63,24 +64,34 @@ export class GremlinService extends Context.Tag('GremlinService')<
/**
* Creates the Gremlin service implementation with dependency injection.
*
- * @returns Effect providing the complete service implementation
- *
- * The service implementation manages:
- * - Connection state through the GremlinClient service
- * - Schema cache with automatic generation and refresh capabilities
- * - Query execution with result transformation and validation
- * - Health monitoring and status reporting
+ * The service wraps all graph operations in a reconnect layer: on any
+ * GremlinConnectionError the cached connection is invalidated and the operation
+ * is retried once with a fresh connection.
*/
const makeGremlinService = Effect.gen(function* () {
const gremlinClient = yield* GremlinClient;
const schemaService = yield* SchemaService;
+ /**
+ * Wraps an Effect so that on GremlinConnectionError the connection is
+ * invalidated and the operation retried exactly once.
+ */
+ const withReconnect = <A, E>(
+ operation: Effect.Effect<A, E | GremlinConnectionError>
+ ): Effect.Effect<A, E | GremlinConnectionError> =>
+ pipe(
+ operation,
+ Effect.catchTag('GremlinConnectionError', () =>
+ pipe(
+ Effect.logWarning('Connection error — invalidating and retrying once'),
+ Effect.andThen(gremlinClient.invalidate),
+ Effect.andThen(operation)
+ )
+ )
+ );
+
/**
* Executes a raw Gremlin query against the client.
- *
- * @param query - Gremlin traversal query string
- * @param client - Gremlin client instance
- * @returns Effect with query results or execution error
*/
const executeRawQuery = (
query: string,
@@ -93,9 +104,6 @@ const makeGremlinService = Effect.gen(function* () {
/**
* Processes Gremlin ResultSet into standard array format.
- *
- * @param resultSet - Raw result from Gremlin client
- * @returns Array of result items
*/
const processResultSet = (resultSet: unknown): unknown[] => {
if (resultSet && typeof resultSet === 'object' && '_items' in resultSet) {
@@ -109,10 +117,6 @@ const makeGremlinService = Effect.gen(function* () {
/**
* Transforms raw result set into parsed GremlinQueryResult format.
- *
- * @param query - Original query string for error context
- * @param resultSet - Raw result set from Gremlin
- * @returns Effect with parsed results and metadata
*/
const transformGremlinResult = (
query: string,
@@ -130,10 +134,6 @@ const makeGremlinService = Effect.gen(function* () {
/**
* Validates query result against the GremlinQueryResult schema.
- *
- * @param query - Original query string for error context
- * @param result - Parsed result object
- * @returns Effect with validated GremlinQueryResult
*/
const validateQueryResult = (
query: string,
@@ -145,17 +145,14 @@ const makeGremlinService = Effect.gen(function* () {
);
/**
- * Executes a Gremlin query with comprehensive error handling.
- *
- * @param query - Gremlin traversal query string
- * @returns Effect with parsed and validated query results
+ * Core query execution — obtains the connection and runs the query.
*/
- const executeQuery = (
+ const doExecuteQuery = (
query: string
): Effect.Effect<GremlinQueryResult, GremlinQueryError | GremlinConnectionError | ParseError> =>
pipe(
- Effect.logDebug(`Executing Gremlin query: ${query}`),
- Effect.andThen(() => executeRawQuery(query, gremlinClient.client)),
+ gremlinClient.getConnection,
+ Effect.flatMap(conn => executeRawQuery(query, conn.client)),
Effect.filterOrFail(isGremlinResult, resultSet =>
Errors.query('Invalid result format received', query, resultSet)
),
@@ -163,18 +160,59 @@ const makeGremlinService = Effect.gen(function* () {
Effect.andThen(parsedResults => validateQueryResult(query, parsedResults))
);
- const getStatus = Effect.succeed({ status: 'connected' as const });
+ /**
+ * Executes a Gremlin query with transparent reconnection on failure.
+ */
+ const executeQuery = (
+ query: string
+ ): Effect.Effect<GremlinQueryResult, GremlinQueryError | GremlinConnectionError | ParseError> =>
+ pipe(
+ Effect.logDebug(`Executing Gremlin query: ${query}`),
+ Effect.andThen(() => withReconnect(doExecuteQuery(query)))
+ );
+
+ /**
+ * Performs a lightweight server round-trip to verify the current connection is still alive.
+ */
+ const verifyConnectionAlive = (
+ conn: ConnectionState
+ ): Effect.Effect<void, GremlinConnectionError> =>
+ pipe(
+ Effect.tryPromise(() => conn.g.inject(1).next()),
+ Effect.asVoid,
+ Effect.mapError(error => Errors.connection('Connection health check failed', error))
+ );
+
+ /**
+ * Returns current connection status without throwing.
+ */
+ const getStatus: Effect.Effect<ServiceStatus, never> = pipe(
+ withReconnect(
+ pipe(
+ gremlinClient.getConnection,
+ Effect.flatMap(conn => verifyConnectionAlive(conn)),
+ Effect.as({ status: 'connected' as const })
+ )
+ ),
+ Effect.catchAll(() => Effect.succeed({ status: 'disconnected' as const }))
+ );
- const healthCheck = Effect.succeed({
- healthy: true,
- details: 'Connected',
- });
+ const healthCheck: Effect.Effect<{ healthy: boolean; details: string }, never> = pipe(
+ withReconnect(
+ pipe(
+ gremlinClient.getConnection,
+ Effect.flatMap(conn => verifyConnectionAlive(conn)),
+ Effect.as({ healthy: true, details: 'Connected' })
+ )
+ ),
+ Effect.catchAll(() => Effect.succeed({ healthy: false, details: 'Connection unavailable' }))
+ );
return {
getStatus,
- getSchema: schemaService.getSchema,
+ getSchema: withReconnect(schemaService.getSchema),
getCachedSchema: schemaService.peekSchema,
- refreshSchemaCache: schemaService.refreshSchema,
+ refreshSchemaCache: withReconnect(schemaService.refreshSchema),
executeQuery,
healthCheck,
} as const;
@@ -183,7 +221,6 @@ const makeGremlinService = Effect.gen(function* () {
/**
* Creates a layer providing the Gremlin service implementation.
*
- * This layer depends on the `GremlinClient` service, which is expected
- * to be provided elsewhere in the application's layer composition.
+ * Depends on `GremlinClient` and `SchemaService`.
*/
export const GremlinServiceLive = Layer.effect(GremlinService, makeGremlinService);
diff --git a/gremlin-mcp/src/main/javascript/src/gremlin/types.ts b/gremlin-mcp/src/main/javascript/src/gremlin/types.ts
index 04cf31720f..cb7c6b072d 100644
--- a/gremlin-mcp/src/main/javascript/src/gremlin/types.ts
+++ b/gremlin-mcp/src/main/javascript/src/gremlin/types.ts
@@ -32,7 +32,7 @@ export type GremlinConnection = driver.DriverRemoteConnection;
export type GraphTraversalSource = process.GraphTraversalSource;
/**
- * Internal connection state - represents a fully initialized connection
+ * Active Gremlin connection state. Only created when the connection succeeds.
*/
export interface ConnectionState {
readonly client: GremlinClientType;
diff --git a/gremlin-mcp/src/main/javascript/src/handlers/resources.ts b/gremlin-mcp/src/main/javascript/src/handlers/resources.ts
index 72fb372e88..092c485d5f 100644
--- a/gremlin-mcp/src/main/javascript/src/handlers/resources.ts
+++ b/gremlin-mcp/src/main/javascript/src/handlers/resources.ts
@@ -9,7 +9,7 @@
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing,
+ * Unless required by applicable law or agreed in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
@@ -21,31 +21,47 @@
* @fileoverview MCP resource handlers for graph database information.
*
* Provides MCP resources that expose real-time graph database status and schema
- * information. Resources are automatically updated and can be subscribed to by
- * MCP clients for live monitoring.
+ * information. Resources are always registered; when no endpoint is configured
+ * they return a "disconnected - configure an endpoint" message.
*/
-import { Effect, pipe, Runtime } from 'effect';
+import { Effect, pipe, Runtime, Option } from 'effect';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { RESOURCE_URIS, MIME_TYPES } from '../constants.js';
-import { ERROR_PREFIXES } from '../errors.js';
import { GremlinService } from '../gremlin/service.js';
+import type { AppConfigType } from '../config.js';
+
+const OFFLINE_STATUS = 'disconnected - configure an endpoint';
+const OFFLINE_SCHEMA = JSON.stringify(
+ {
+ status: 'disconnected',
+ message: 'Configure `GREMLIN_MCP_ENDPOINT` to enable graph operations.',
+ },
+ null,
+ 2
+);
/**
* Registers MCP resource handlers with the server.
*
+ * Both resources are always registered. When no endpoint is configured the
+ * responses contain a static "disconnected" message; otherwise the live
+ * Gremlin service is queried.
+ *
* @param server - MCP server instance
* @param runtime - Effect runtime with Gremlin service
- *
- * Registers resources for:
- * - Graph connection status monitoring
- * - Live schema information access
+ * @param config - Application configuration
*/
export function registerEffectResourceHandlers(
server: McpServer,
- runtime: Runtime.Runtime<GremlinService>
+ runtime: Runtime.Runtime<GremlinService>,
+ config: AppConfigType
): void {
- // Register status resource using the recommended registerResource method
+ const endpointFromEnv = process.env['GREMLIN_MCP_ENDPOINT'] ?? '';
+ const endpointIsConfiguredInEnv = endpointFromEnv.trim() !== '';
+ const hasEndpoint = endpointIsConfiguredInEnv && Option.isSome(config.gremlin.endpoint);
+
+ // Register status resource
server.registerResource(
'status',
RESOURCE_URIS.STATUS,
@@ -54,13 +70,25 @@ export function registerEffectResourceHandlers(
description: 'Real-time connection status of the Gremlin graph database',
mimeType: MIME_TYPES.TEXT_PLAIN,
},
- () =>
- Effect.runPromise(
+ (_uri, _extra) => {
+ if (!hasEndpoint) {
+ return Promise.resolve({
+ contents: [
+ {
+ uri: RESOURCE_URIS.STATUS,
+ mimeType: MIME_TYPES.TEXT_PLAIN,
+ text: OFFLINE_STATUS,
+ },
+ ],
+ });
+ }
+
+ return Effect.runPromise(
pipe(
GremlinService,
Effect.andThen(service => service.getStatus),
Effect.map(statusObj => statusObj.status),
- Effect.catchAll(error => Effect.succeed(`${ERROR_PREFIXES.CONNECTION}: ${error}`)),
+ Effect.catchAll(error => Effect.succeed(String(error))),
Effect.provide(runtime)
)
).then(result => ({
@@ -71,10 +99,11 @@ export function registerEffectResourceHandlers(
text: result,
},
],
- }))
+ }));
+ }
);
- // Register schema resource using the recommended registerResource method
+ // Register schema resource
server.registerResource(
'schema',
RESOURCE_URIS.SCHEMA,
@@ -84,12 +113,26 @@ export function registerEffectResourceHandlers(
'Complete schema of the graph including vertex labels, edge labels, and relationship patterns',
mimeType: MIME_TYPES.APPLICATION_JSON,
},
- () =>
- Effect.runPromise(
+ (_uri, _extra) => {
+ if (!hasEndpoint) {
+ return Promise.resolve({
+ contents: [
+ {
+ uri: RESOURCE_URIS.SCHEMA,
+ mimeType: MIME_TYPES.APPLICATION_JSON,
+ text: OFFLINE_SCHEMA,
+ },
+ ],
+ });
+ }
+
+ return Effect.runPromise(
pipe(
GremlinService,
Effect.andThen(service => service.getSchema),
- Effect.catchAll(error => Effect.succeed({ error: String(error) })),
+ Effect.catchAll(error =>
+ Effect.succeed({ status: 'disconnected', message: String(error) })
+ ),
Effect.provide(runtime)
)
).then(result => ({
@@ -100,6 +143,7 @@ export function registerEffectResourceHandlers(
text: JSON.stringify(result, null, 2),
},
],
- }))
+ }));
+ }
);
}
diff --git a/gremlin-mcp/src/main/javascript/src/handlers/tools.ts b/gremlin-mcp/src/main/javascript/src/handlers/tools.ts
index bb143804fc..f9173b6a12 100644
--- a/gremlin-mcp/src/main/javascript/src/handlers/tools.ts
+++ b/gremlin-mcp/src/main/javascript/src/handlers/tools.ts
@@ -25,7 +25,7 @@
* for service access.
*/
-import { Effect, Runtime, pipe } from 'effect';
+import { Effect, Runtime, Option, pipe } from 'effect';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { TOOL_NAMES } from '../constants.js';
@@ -33,10 +33,17 @@ import { GremlinService } from '../gremlin/service.js';
import {
createToolEffect,
createStringToolEffect,
- createQueryEffect,
createSuccessResponse,
} from './tool-patterns.js';
import { formatQuery } from 'gremlint';
+import { GremlinTranslator } from 'gremlin-language/language';
+import { normalizeAndTranslate } from '../translator/index.js';
+import type { AppConfigType } from '../config.js';
+import {
+ markGremlinConnected,
+ markGremlinDisconnected,
+ isGremlinConnectionError,
+} from '../connectivity-state.js';
/**
* Input validation schemas for tool parameters.
@@ -68,21 +75,119 @@ const formatQueryInputSchema = z
})
.strict();
+// Translate Gremlin Query input
+const TRANSLATE_TARGETS = [
+ 'canonical',
+ 'javascript',
+ 'python',
+ 'go',
+ 'dotnet',
+ 'java',
+ 'groovy',
+ 'anonymized',
+] as const;
+type TranslateTarget = (typeof TRANSLATE_TARGETS)[number];
+
+const toUnknownRecord = (value: unknown): Record<string, unknown> | null =>
+ typeof value === 'object' && value !== null ? (value as Record<string, unknown>) : null;
+
+const TARGET_TO_TRANSLATOR_KEY: Record<TranslateTarget, string> = {
+ canonical: 'CANONICAL',
+ javascript: 'JAVASCRIPT',
+ python: 'PYTHON',
+ go: 'GO',
+ dotnet: 'DOTNET',
+ java: 'JAVA',
+ groovy: 'GROOVY',
+ anonymized: 'ANONYMIZED',
+};
+
+const TRANSLATE_SOURCES = [
+ 'canonical',
+ 'javascript',
+ 'python',
+ 'go',
+ 'dotnet',
+ 'java',
+ 'groovy',
+ 'auto',
+] as const;
+
+const translateQueryInputSchema = z
+ .object({
+ gremlin: z
+ .string()
+ .min(1, 'The Gremlin query cannot be empty')
+ .describe(
+ 'The Gremlin query string to translate. When source is omitted or "canonical", must use gremlin-language ANTLR grammar format. For any other source value, the query will be normalized automatically.'
+ ),
+ target: z.enum(TRANSLATE_TARGETS).describe('The target language to translate into'),
+ source: z
+ .enum(TRANSLATE_SOURCES)
+ .optional()
+ .describe(
+ 'The source dialect of the input query. Omit or use "auto" to normalize automatically via LLM before translating (default behavior). Use "canonical" to skip normalization and translate directly (only if your input is already in canonical gremlin-language ANTLR format).'
+ ),
+ traversalSource: z
+ .string()
+ .optional()
+ .describe('The traversal source variable name (default: "g")'),
+ })
+ .strict();
+
/**
- * Registers all MCP tool handlers with the server.
+ * Registers MCP tool handlers with the server.
+ *
+ * Graph tools (status, schema, query) are only registered when a Gremlin endpoint is configured. Utility tools (translate, format) are always registered.
*
* @param server - MCP server instance
* @param runtime - Effect runtime with Gremlin service
- *
- * Registers tools for:
- * - Graph status monitoring
- * - Schema introspection and caching
- * - Query execution
+ * @param config - Application configuration
*/
export function registerEffectToolHandlers(
server: McpServer,
- runtime: Runtime.Runtime<GremlinService>
+ runtime: Runtime.Runtime<GremlinService>,
+ config: AppConfigType
): void {
+ if (Option.isSome(config.gremlin.endpoint)) {
+ registerGraphTools(server, runtime);
+ }
+ registerUtilityTools(server, runtime);
+}
+
+/**
+ * Registers graph-connectivity tools (status, schema, query).
+ * Only called when a Gremlin endpoint is configured.
+ */
+function registerGraphTools(server: McpServer, runtime: Runtime.Runtime<GremlinService>): void {
+ const withOperationConnectivityTracking = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
+ pipe(
+ effect,
+ Effect.tap(() => Effect.sync(markGremlinConnected)),
+ Effect.tapError(error =>
+ Effect.sync(() => {
+ if (isGremlinConnectionError(error)) {
+ markGremlinDisconnected();
+ }
+ })
+ )
+ );
+
+ const getTrackedStatus = pipe(
+ GremlinService,
+ Effect.andThen(service => service.getStatus),
+ Effect.tap(statusObj =>
+ Effect.sync(() => {
+ if (statusObj.status === 'connected') {
+ markGremlinConnected();
+ } else {
+ markGremlinDisconnected();
+ }
+ })
+ ),
+ Effect.map(statusObj => statusObj.status)
+ );
+
// Get Graph Status
server.registerTool(
TOOL_NAMES.GET_GRAPH_STATUS,
@@ -94,12 +199,7 @@ export function registerEffectToolHandlers(
() =>
Effect.runPromise(
pipe(
- createStringToolEffect(
- Effect.andThen(GremlinService, service =>
- Effect.map(service.getStatus, statusObj => statusObj.status)
- ),
- 'Connection status check failed'
- ),
+ createStringToolEffect(getTrackedStatus, 'Connection status check failed'),
Effect.provide(runtime)
)
)
@@ -118,7 +218,9 @@ export function registerEffectToolHandlers(
Effect.runPromise(
pipe(
createToolEffect(
- Effect.andThen(GremlinService, service => service.getSchema),
+ withOperationConnectivityTracking(
+ Effect.andThen(GremlinService, service => service.getSchema)
+ ),
'Schema retrieval failed'
),
Effect.provide(runtime)
@@ -138,8 +240,10 @@ export function registerEffectToolHandlers(
Effect.runPromise(
pipe(
createStringToolEffect(
- Effect.andThen(GremlinService, service =>
- Effect.map(service.refreshSchemaCache, () => 'Schema cache refreshed successfully.')
+ withOperationConnectivityTracking(
+ Effect.andThen(GremlinService, service =>
+ Effect.map(service.refreshSchemaCache, () => 'Schema cache refreshed successfully.')
+ )
),
'Failed to refresh schema'
),
@@ -158,7 +262,101 @@ export function registerEffectToolHandlers(
},
(args: unknown) => {
const { query } = runQueryInputSchema.parse(args);
- return Effect.runPromise(pipe(createQueryEffect(query), Effect.provide(runtime)));
+ return Effect.runPromise(
+ pipe(
+ GremlinService,
+ Effect.andThen(service => withOperationConnectivityTracking(service.executeQuery(query))),
+ Effect.map(createSuccessResponse),
+ Effect.catchAll(error => {
+ const errorResponse = {
+ results: [],
+ message: `Query failed: ${error}`,
+ };
+ return Effect.succeed(createSuccessResponse(errorResponse));
+ }),
+ Effect.provide(runtime)
+ )
+ );
+ }
+ );
+}
+
+/**
+ * Registers utility tools (translate, format) that do not require a Gremlin server.
+ * Always registered regardless of endpoint configuration.
+ */
+function registerUtilityTools(server: McpServer, runtime: Runtime.Runtime<GremlinService>): void {
+ // Translate Gremlin Query
+ server.registerTool(
+ TOOL_NAMES.TRANSLATE_GREMLIN_QUERY,
+ {
+ title: 'Translate Gremlin Query',
+ description:
+ 'Translate a Gremlin query into another language variant. By default, automatically normalizes the input via LLM before translating. Set source to "canonical" to skip normalization if the input is already in canonical gremlin-language ANTLR format.',
+ inputSchema: translateQueryInputSchema.shape,
+ },
+ (args: unknown) => {
+ const { gremlin, target, source, traversalSource } = translateQueryInputSchema.parse(args);
+ const translatorKey = TARGET_TO_TRANSLATOR_KEY[target];
+ const tsource = traversalSource ?? 'g';
+
+ if (source === 'canonical') {
+ // Approach 1: direct translation, canonical input assumed
+ try {
+ const result = GremlinTranslator.translate(
+ gremlin,
+ tsource,
+ translatorKey as Parameters<typeof GremlinTranslator.translate>[2]
+ );
+ return Promise.resolve(
+ createSuccessResponse({
+ success: true,
+ original: result.getOriginal(),
+ translated: result.getTranslated(),
+ target,
+ })
+ );
+ } catch (error) {
+ return Promise.resolve(
+ createSuccessResponse({
+ success: false,
+ error: error instanceof Error ? error.message : String(error),
+ target,
+ })
+ );
+ }
+ }
+
+ // Approach 2+5: mechanical normalization then LLM normalization via MCP sampling
+ return Effect.runPromise(
+ pipe(
+ Effect.tryPromise(() =>
+ normalizeAndTranslate(gremlin, translatorKey, tsource, server.server)
+ ),
+ Effect.map(result =>
+ createSuccessResponse({
+ success: true,
+ original: result.original,
+ normalized: result.normalized,
+ translated: result.translated,
+ target,
+ ...(result.llmNormalizationSkipped && {
+ warning:
+ 'LLM normalization unavailable; result is based on mechanical normalization only and may be less accurate.',
+ }),
+ })
+ ),
+ Effect.catchAll(error =>
+ Effect.succeed(
+ createSuccessResponse({
+ success: false,
+ error: error instanceof Error ? error.message : String(error),
+ target,
+ })
+ )
+ )
+ )
+ );
}
);
@@ -197,9 +395,15 @@ export function registerEffectToolHandlers(
error: {
message: String(error),
// include common error fields when present to make it structured
- name: (error && (error as any).name) || undefined,
- stack: (error && (error as any).stack) || undefined,
- details: (error && (error as any).details) || undefined,
+ name:
+ toUnknownRecord(error) && typeof toUnknownRecord(error)?.['name'] === 'string'
+ ? (toUnknownRecord(error)?.['name'] as string)
+ : undefined,
+ stack:
+ toUnknownRecord(error) && typeof toUnknownRecord(error)?.['stack'] === 'string'
+ ? (toUnknownRecord(error)?.['stack'] as string)
+ : undefined,
+ details: toUnknownRecord(error)?.['details'],
},
})
)
diff --git a/gremlin-mcp/src/main/javascript/src/server.ts b/gremlin-mcp/src/main/javascript/src/server.ts
index 853f2030b5..cf68e0abea 100644
--- a/gremlin-mcp/src/main/javascript/src/server.ts
+++ b/gremlin-mcp/src/main/javascript/src/server.ts
@@ -29,13 +29,23 @@
* Built with Effect-ts for functional composition and error handling.
*/
-import { ConfigProvider, Effect, Layer, pipe, LogLevel, Logger, Context, Fiber } from 'effect';
+import {
+ ConfigProvider,
+ Effect,
+ Layer,
+ pipe,
+ LogLevel,
+ Logger,
+ Context,
+ Fiber,
+ Option,
+} from 'effect';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { AppConfig, type AppConfigType } from './config.js';
import { GremlinService, GremlinServiceLive } from './gremlin/service.js';
-import { GremlinClientLive } from './gremlin/connection.js';
+import { GremlinClient } from './gremlin/client.js';
import { SchemaServiceLive } from './gremlin/schema.js';
import { registerEffectToolHandlers } from './handlers/tools.js';
import { registerEffectResourceHandlers } from './handlers/resources.js';
@@ -85,8 +95,8 @@ const makeMcpServerService = Effect.gen(function* () {
const runtime = yield* Effect.runtime<GremlinService>();
// Register handlers with dependency injection
- registerEffectToolHandlers(server, runtime);
- registerEffectResourceHandlers(server, runtime);
+ registerEffectToolHandlers(server, runtime, config);
+ registerEffectResourceHandlers(server, runtime, config);
yield* Effect.logInfo('✅ Handlers registered successfully', {
service: config.server.name,
@@ -130,13 +140,44 @@ const McpServerServiceLive = Layer.effect(McpServerService, makeMcpServerService
/**
* Layer composition providing all application dependencies.
+ *
+ * When GREMLIN_MCP_ENDPOINT is not set we use a gremlin-free offline stub so
+ * the gremlin driver is never imported or instantiated. When it IS set we
+ * dynamically import the real GremlinClientLive (which pulls in the driver).
*/
-const GremlinLayer = Layer.provide(GremlinServiceLive, SchemaServiceLive);
-const AppLayer = Layer.provide(
- McpServerServiceLive,
- Layer.provide(GremlinLayer, GremlinClientLive)
+const NO_ENDPOINT_MSG =
+ 'No Gremlin Server configured. Set GREMLIN_MCP_ENDPOINT to enable graph operations.';
+
+const GremlinClientOfflineLive = Layer.succeed(
+ GremlinClient,
+ GremlinClient.of({
+ getConnection: Effect.fail(Errors.connection(NO_ENDPOINT_MSG)),
+ invalidate: Effect.void,
+ })
);
+const GremlinLayer = Layer.provide(GremlinServiceLive, SchemaServiceLive);
+
+// Choose the client layer based purely on whether the env var is present at startup.
+// This is checked before any Effect runs so the gremlin driver is never loaded when
+// no endpoint is configured.
+const endpointIsConfigured =
+ process.env['GREMLIN_MCP_ENDPOINT'] !== undefined &&
+ process.env['GREMLIN_MCP_ENDPOINT'].trim() !== '';
+
+// Dynamically import the real client layer only when an endpoint is provided,
+// keeping the gremlin driver out of the module graph in offline mode.
+const getGremlinClientLayer = async () => {
+ if (!endpointIsConfigured) {
+ return GremlinClientOfflineLive;
+ }
+ const { GremlinClientLive } = await import('./gremlin/connection.js');
+ return GremlinClientLive;
+};
+
+// Resolved once at startup; used below in AppLayer.
+const GremlinClientLayerPromise = getGremlinClientLayer();
+
/**
* Main application Effect.
*
@@ -147,10 +188,23 @@ const program = Effect.gen(function* () {
// Get configuration
const config = yield* AppConfig;
+ const endpointInfo = Option.match(config.gremlin.endpoint, {
+ onNone: () => ({ configured: false }),
+ onSome: ep => ({
+ configured: true,
+ host: ep.host,
+ port: ep.port,
+ traversalSource: ep.traversalSource,
+ }),
+ });
+
yield* Effect.logInfo('🚀 Starting Apache TinkerPop Gremlin MCP Server...', {
service: config.server.name,
version: config.server.version,
- gremlinEndpoint: `${config.gremlin.host}:${config.gremlin.port}`,
+ gremlinEndpoint: Option.match(config.gremlin.endpoint, {
+ onNone: () => '(none)',
+ onSome: ep => `${ep.host}:${ep.port}`,
+ }),
logLevel: config.logging.level,
config: {
server: {
@@ -158,13 +212,11 @@ const program = Effect.gen(function* () {
version: config.server.version,
},
gremlin: {
- host: config.gremlin.host,
- port: config.gremlin.port,
- traversalSource: config.gremlin.traversalSource,
+ ...endpointInfo,
useSSL: config.gremlin.useSSL,
idleTimeout: config.gremlin.idleTimeout,
- username: config.gremlin.username ?? null,
- hasPassword: Boolean(config.gremlin.password),
+ username: Option.getOrNull(config.gremlin.username),
+ hasPassword: Option.isSome(config.gremlin.password),
},
schema: {
enumDiscoveryEnabled: config.schema.enumDiscoveryEnabled,
@@ -303,69 +355,97 @@ const withGracefulShutdown = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.E
});
/**
- * Main entry point with full Effect composition
+ * Main entry point with full Effect composition.
+ *
+ * @param appLayer - Fully composed application layer (built after resolving the
+ * gremlin client layer asynchronously so the gremlin driver is never imported
+ * when GREMLIN_MCP_ENDPOINT is not set).
*/
-const main = Effect.gen(function* () {
- // Add startup logging before anything else - CRITICAL: Use stderr only
- yield* logToStderr({
- level: 'info',
- message: 'Apache TinkerPop - Gremlin MCP Server executable started',
- process_info: {
- pid: process.pid,
- node_version: process.versions.node,
- platform: process.platform,
- argv: process.argv,
- cwd: process.cwd(),
- },
- });
-
- // Get configuration early for logging setup
- const config = yield* AppConfig;
-
- // Log configuration
- yield* logToStderr({
- level: 'info',
- message: 'Configuration loaded',
- config: {
- gremlin: {
- host: config.gremlin.host,
- port: config.gremlin.port,
- use_ssl: config.gremlin.useSSL,
- traversal_source: config.gremlin.traversalSource,
- idle_timeout: config.gremlin.idleTimeout,
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const main = (appLayer: Layer.Layer<McpServerService, any, never>) =>
+ Effect.gen(function* () {
+ // Add startup logging before anything else - CRITICAL: Use stderr only
+ yield* logToStderr({
+ level: 'info',
+ message: 'Apache TinkerPop - Gremlin MCP Server executable started',
+ process_info: {
+ pid: process.pid,
+ node_version: process.versions.node,
+ platform: process.platform,
+ argv: process.argv,
+ cwd: process.cwd(),
},
- logging: {
- level: config.logging.level,
+ });
+
+ // Get configuration early for logging setup
+ const config = yield* AppConfig;
+
+ // Log configuration
+ yield* logToStderr({
+ level: 'info',
+ message: 'Configuration loaded',
+ config: {
+ gremlin: Option.match(config.gremlin.endpoint, {
+ onNone: () => ({
+ configured: false,
+ use_ssl: config.gremlin.useSSL,
+ idle_timeout: config.gremlin.idleTimeout,
+ }),
+ onSome: ep => ({
+ configured: true,
+ host: ep.host,
+ port: ep.port,
+ use_ssl: config.gremlin.useSSL,
+ traversal_source: ep.traversalSource,
+ idle_timeout: config.gremlin.idleTimeout,
+ }),
+ }),
+ logging: {
+ level: config.logging.level,
+ },
},
- },
+ });
+
+ // Run the main program with all services provided
+ yield* pipe(
+ withGracefulShutdown(program),
+ Effect.provide(appLayer),
+ Effect.provide(createLoggerLayer(config))
+ );
});
- // Run the main program with all services provided
- yield* pipe(
- withGracefulShutdown(program),
- Effect.provide(AppLayer),
- Effect.provide(createLoggerLayer(config))
- );
-});
-
/**
- * Run the application with improved error handling using Effect patterns
+ * Run the application with improved error handling using Effect patterns.
+ *
+ * Async so we can await the gremlin client layer resolution before building the
+ * full layer graph and starting the Effect runtime.
*/
// Ensure environment variables are used for configuration resolution across the app
const EnvConfigLayer = Layer.setConfigProvider(ConfigProvider.fromEnv());
-const runMain = pipe(
- Effect.scoped(main),
- Effect.provide(EnvConfigLayer),
- Effect.catchAll((error: unknown) =>
- logToStderr({
- level: 'error',
- message: 'Fatal error in main program',
- error: error instanceof Error ? error.message : String(error),
- error_type: error instanceof Error ? error.constructor.name : typeof error,
- stack: error instanceof Error ? error.stack : undefined,
- }).pipe(Effect.andThen(() => Effect.sync(() => process.exit(1))))
- )
-);
+async function run(): Promise<void> {
+ const gremlinClientLayer = await GremlinClientLayerPromise;
+
+ const AppLayer = Layer.provide(
+ McpServerServiceLive,
+ Layer.provide(GremlinLayer, gremlinClientLayer)
+ );
+
+ const runMain = pipe(
+ Effect.scoped(main(AppLayer)),
+ Effect.provide(EnvConfigLayer),
+ Effect.catchAll((error: unknown) =>
+ logToStderr({
+ level: 'error',
+ message: 'Fatal error in main program',
+ error: error instanceof Error ? error.message : String(error),
+ error_type: error instanceof Error ? error.constructor.name : typeof error,
+ stack: error instanceof Error ? error.stack : undefined,
+ }).pipe(Effect.andThen(() => Effect.sync(() => process.exit(1))))
+ )
+ );
+
+ await Effect.runPromise(runMain);
+}
-Effect.runPromise(runMain);
+run();
diff --git a/gremlin-mcp/src/main/javascript/src/translator/index.ts b/gremlin-mcp/src/main/javascript/src/translator/index.ts
new file mode 100644
index 0000000000..05f187c442
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/src/translator/index.ts
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileoverview Orchestrates the normalize-and-translate pipeline.
+ *
+ * Pipeline:
+ * 1. Mechanical pre-processing (gremlingo. strip, trailing _, PascalCase→camelCase)
+ * 2. LLM normalization via MCP sampling (handles remaining dialect-specific constructs)
+ * 3. GremlinTranslator.translate() to the target language
+ */
+
+import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
+import { GremlinTranslator } from 'gremlin-language/language';
+import { applyMechanicalNormalization } from './normalizers/shared.js';
+import { normalizeWithLlm } from './llm.js';
+
+export interface NormalizeAndTranslateResult {
+ readonly original: string;
+ readonly normalized: string;
+ readonly translated: string;
+ readonly llmNormalizationSkipped: boolean;
+}
+
+/**
+ * Normalizes a Gremlin query from any dialect to canonical format, then translates
+ * it to the specified target language.
+ *
+ * @param query - Input Gremlin query in any dialect
+ * @param target - Translator key (e.g. 'JAVASCRIPT', 'PYTHON')
+ * @param traversalSource - Traversal source variable name (default: 'g')
+ * @param server - MCP server instance for LLM sampling
+ * @returns Original, normalized, and translated query strings
+ */
+export async function normalizeAndTranslate(
+ query: string,
+ target: string,
+ traversalSource: string,
+ server: Server
+): Promise<NormalizeAndTranslateResult> {
+ const mechanical = applyMechanicalNormalization(query);
+ const [normalized, llmNormalizationSkipped] = await normalizeWithLlm(mechanical, server)
+ .then((result): [string, boolean] => [result, false])
+ .catch((): [string, boolean] => [mechanical, true]);
+ const result = GremlinTranslator.translate(
+ normalized,
+ traversalSource,
+ target as Parameters<typeof GremlinTranslator.translate>[2]
+ );
+ return {
+ original: query,
+ normalized,
+ translated: result.getTranslated(),
+ llmNormalizationSkipped,
+ };
+}
diff --git a/gremlin-mcp/src/main/javascript/src/translator/llm.ts b/gremlin-mcp/src/main/javascript/src/translator/llm.ts
new file mode 100644
index 0000000000..3339f98dc7
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/src/translator/llm.ts
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileoverview LLM-based normalization of Gremlin queries to canonical format.
+ *
+ * Uses MCP sampling to request normalization from the host LLM client, requiring
+ * no API key and no dependency on any specific LLM provider.
+ */
+
+import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
+
+const SYSTEM_PROMPT = `You are a Gremlin query normalizer. Convert the given Gremlin query to canonical gremlin-language ANTLR grammar format.
+
+Canonical format rules:
+- Step names are camelCase: out(), hasLabel(), values() — not PascalCase
+- Boolean literals are lowercase: true, false — not True, False
+- Null literal is: null — not None
+- No language-specific prefixes (gremlingo. has already been stripped)
+- Enum values use canonical casing: T.label, T.id, T.key, T.value; Direction.OUT, Direction.IN, Direction.BOTH; Order.asc, Order.desc, Order.shuffle; Scope.local, Scope.global; Pop.first, Pop.last, Pop.all, Pop.mixed; Merge.onCreate, Merge.onMatch, Merge.outV, Merge.inV; Cardinality.single, Cardinality.list, Cardinality.set
+- No type casts: use null instead of (Map) null, (Object) null, (String) null, etc.
+- Collection literals: [a, b, c] for lists, {a, b, c} for sets, ["key": value] for maps
+- Date literals: datetime("2023-01-01T00:00:00Z") — not OffsetDateTime.parse(...)
+- UUID literals: uuid("...") or uuid() — not UUID.fromString(...) or UUID.randomUUID()
+- No Java collection constructors (new ArrayList<>(), new HashSet<>(), new LinkedHashMap<>()) — use list/set/map literals
+
+Return ONLY the normalized Gremlin query. No explanation, no markdown, no surrounding text.`;
+
+/**
+ * Normalizes a Gremlin query to canonical format using MCP sampling.
+ * Delegates to the host LLM client — no API key or vendor dependency required.
+ *
+ * @param query - Pre-processed Gremlin query (after mechanical normalization)
+ * @param server - MCP server instance used to issue the sampling request
+ * @returns Normalized canonical Gremlin query string
+ * @throws If the client does not support sampling or the response is not text
+ */
+export async function normalizeWithLlm(query: string, server: Server): Promise<string> {
+ const result = await server.createMessage({
+ messages: [{ role: 'user', content: { type: 'text', text: query } }],
+ systemPrompt: SYSTEM_PROMPT,
+ maxTokens: 1024,
+ });
+
+ if (result.content.type !== 'text') {
+ throw new Error('Unexpected response type from LLM normalization');
+ }
+
+ return result.content.text.trim();
+}
diff --git a/gremlin-mcp/src/main/javascript/src/translator/normalizers/shared.ts b/gremlin-mcp/src/main/javascript/src/translator/normalizers/shared.ts
new file mode 100644
index 0000000000..82f2ebf692
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/src/translator/normalizers/shared.ts
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileoverview Mechanical pre-normalization transforms applied before LLM normalization.
+ *
+ * These transforms are cheap, deterministic, and language-agnostic. They reduce noise
+ * before the LLM sees the query:
+ * 1. Strip gremlingo. prefix (Go dialect)
+ * 2. Strip trailing _ from known step names (reserved word workarounds)
+ * 3. Convert PascalCase step names to camelCase (Go/.NET dialects)
+ */
+
+import { GREMLIN_STEP_NAMES, GREMLIN_STEP_NAMES_PASCAL } from '../stepNames.js';
+
+/**
+ * Applies mechanical pre-normalization to a Gremlin query string.
+ * Safe to apply to any dialect including canonical — transforms are idempotent.
+ */
+export function applyMechanicalNormalization(query: string): string {
+ let result = query;
+
+ // 1. Strip gremlingo. prefix
+ result = result.replace(/gremlingo\./g, '');
+
+ // 2. Strip trailing _ from known step names before (
+ // e.g. in_( → in(, from_( → from(
+ // Only applies to names in GREMLIN_STEP_NAMES to avoid corrupting user identifiers.
+ result = result.replace(/\b(\w+)_\s*\(/g, (_match, name: string) => {
+ if (GREMLIN_STEP_NAMES.has(name)) {
+ return `${name}(`;
+ }
+ return _match;
+ });
+
+ // 3. Convert PascalCase step names → camelCase
+ // e.g. HasLabel( → hasLabel(, Out( → out(
+ // Only converts tokens where (a) the PascalCase form is in GREMLIN_STEP_NAMES_PASCAL and
+ // (b) the resulting camelCase form is in GREMLIN_STEP_NAMES. The second check handles
+ // steps like V and E whose canonical form is already uppercase — converting them to
+ // v( or e( would be wrong.
+ result = result.replace(/\b([A-Z][a-zA-Z0-9]*)\s*\(/g, (_match, name: string) => {
+ if (GREMLIN_STEP_NAMES_PASCAL.has(name)) {
+ const camel = `${name.charAt(0).toLowerCase()}${name.slice(1)}`;
+ if (GREMLIN_STEP_NAMES.has(camel)) {
+ return `${camel}(`;
+ }
+ }
+ return _match;
+ });
+
+ return result;
+}
diff --git a/gremlin-mcp/src/main/javascript/src/translator/stepNames.ts b/gremlin-mcp/src/main/javascript/src/translator/stepNames.ts
new file mode 100644
index 0000000000..c6269f6769
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/src/translator/stepNames.ts
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Generated by scripts/generate-step-names.js — do not edit manually.
+// Re-run `npm run generate-step-names` after changes to Gremlin.g4.
+
+/**
+ * Canonical camelCase Gremlin step names derived from the gremlin-language grammar.
+ * Used to safely identify step names during normalization.
+ */
+export const GREMLIN_STEP_NAMES: ReadonlySet<string> = new Set([
+ 'E',
+ 'V',
+ 'addE',
+ 'addV',
+ 'aggregate',
+ 'all',
+ 'and',
+ 'any',
+ 'as',
+ 'asBool',
+ 'asDate',
+ 'asString',
+ 'barrier',
+ 'both',
+ 'bothE',
+ 'bothV',
+ 'branch',
+ 'by',
+ 'call',
+ 'cap',
+ 'choose',
+ 'coalesce',
+ 'coin',
+ 'combine',
+ 'concat',
+ 'conjoin',
+ 'connectedComponent',
+ 'constant',
+ 'count',
+ 'cyclicPath',
+ 'dateAdd',
+ 'dateDiff',
+ 'dedup',
+ 'difference',
+ 'discard',
+ 'disjunct',
+ 'drop',
+ 'element',
+ 'elementMap',
+ 'emit',
+ 'fail',
+ 'filter',
+ 'flatMap',
+ 'fold',
+ 'format',
+ 'from',
+ 'group',
+ 'groupCount',
+ 'has',
+ 'hasId',
+ 'hasKey',
+ 'hasLabel',
+ 'hasNot',
+ 'hasValue',
+ 'id',
+ 'identity',
+ 'in',
+ 'inE',
+ 'inV',
+ 'index',
+ 'inject',
+ 'intersect',
+ 'io',
+ 'is',
+ 'key',
+ 'lTrim',
+ 'label',
+ 'length',
+ 'limit',
+ 'local',
+ 'loops',
+ 'map',
+ 'match',
+ 'math',
+ 'max',
+ 'mean',
+ 'merge',
+ 'mergeE',
+ 'mergeV',
+ 'min',
+ 'none',
+ 'not',
+ 'option',
+ 'optional',
+ 'or',
+ 'order',
+ 'otherV',
+ 'out',
+ 'outE',
+ 'outV',
+ 'pageRank',
+ 'path',
+ 'peerPressure',
+ 'product',
+ 'profile',
+ 'project',
+ 'properties',
+ 'property',
+ 'propertyMap',
+ 'rTrim',
+ 'range',
+ 'read',
+ 'repeat',
+ 'replace',
+ 'reverse',
+ 'sack',
+ 'sample',
+ 'select',
+ 'shortestPath',
+ 'sideEffect',
+ 'simplePath',
+ 'skip',
+ 'split',
+ 'subgraph',
+ 'substring',
+ 'sum',
+ 'tail',
+ 'timeLimit',
+ 'times',
+ 'to',
+ 'toE',
+ 'toLower',
+ 'toUpper',
+ 'toV',
+ 'tree',
+ 'trim',
+ 'unfold',
+ 'union',
+ 'until',
+ 'value',
+ 'valueMap',
+ 'values',
+ 'where',
+ 'with',
+ 'write',
+]);
+
+/**
+ * PascalCase equivalents of Gremlin step names, as used by Go and .NET dialects.
+ * Used as an allowlist when converting PascalCase tokens to camelCase during normalization.
+ */
+export const GREMLIN_STEP_NAMES_PASCAL: ReadonlySet<string> = new Set([
+ 'E',
+ 'V',
+ 'AddE',
+ 'AddV',
+ 'Aggregate',
+ 'All',
+ 'And',
+ 'Any',
+ 'As',
+ 'AsBool',
+ 'AsDate',
+ 'AsString',
+ 'Barrier',
+ 'Both',
+ 'BothE',
+ 'BothV',
+ 'Branch',
+ 'By',
+ 'Call',
+ 'Cap',
+ 'Choose',
+ 'Coalesce',
+ 'Coin',
+ 'Combine',
+ 'Concat',
+ 'Conjoin',
+ 'ConnectedComponent',
+ 'Constant',
+ 'Count',
+ 'CyclicPath',
+ 'DateAdd',
+ 'DateDiff',
+ 'Dedup',
+ 'Difference',
+ 'Discard',
+ 'Disjunct',
+ 'Drop',
+ 'Element',
+ 'ElementMap',
+ 'Emit',
+ 'Fail',
+ 'Filter',
+ 'FlatMap',
+ 'Fold',
+ 'Format',
+ 'From',
+ 'Group',
+ 'GroupCount',
+ 'Has',
+ 'HasId',
+ 'HasKey',
+ 'HasLabel',
+ 'HasNot',
+ 'HasValue',
+ 'Id',
+ 'Identity',
+ 'In',
+ 'InE',
+ 'InV',
+ 'Index',
+ 'Inject',
+ 'Intersect',
+ 'Io',
+ 'Is',
+ 'Key',
+ 'LTrim',
+ 'Label',
+ 'Length',
+ 'Limit',
+ 'Local',
+ 'Loops',
+ 'Map',
+ 'Match',
+ 'Math',
+ 'Max',
+ 'Mean',
+ 'Merge',
+ 'MergeE',
+ 'MergeV',
+ 'Min',
+ 'None',
+ 'Not',
+ 'Option',
+ 'Optional',
+ 'Or',
+ 'Order',
+ 'OtherV',
+ 'Out',
+ 'OutE',
+ 'OutV',
+ 'PageRank',
+ 'Path',
+ 'PeerPressure',
+ 'Product',
+ 'Profile',
+ 'Project',
+ 'Properties',
+ 'Property',
+ 'PropertyMap',
+ 'RTrim',
+ 'Range',
+ 'Read',
+ 'Repeat',
+ 'Replace',
+ 'Reverse',
+ 'Sack',
+ 'Sample',
+ 'Select',
+ 'ShortestPath',
+ 'SideEffect',
+ 'SimplePath',
+ 'Skip',
+ 'Split',
+ 'Subgraph',
+ 'Substring',
+ 'Sum',
+ 'Tail',
+ 'TimeLimit',
+ 'Times',
+ 'To',
+ 'ToE',
+ 'ToLower',
+ 'ToUpper',
+ 'ToV',
+ 'Tree',
+ 'Trim',
+ 'Unfold',
+ 'Union',
+ 'Until',
+ 'Value',
+ 'ValueMap',
+ 'Values',
+ 'Where',
+ 'With',
+ 'Write',
+]);
diff --git a/gremlin-mcp/src/main/javascript/tests/config.test.ts b/gremlin-mcp/src/main/javascript/tests/config.test.ts
index ed489009ab..b2467fad49 100644
--- a/gremlin-mcp/src/main/javascript/tests/config.test.ts
+++ b/gremlin-mcp/src/main/javascript/tests/config.test.ts
@@ -56,11 +56,12 @@ describe('Effect-based Configuration Management', () => {
const result = await Effect.runPromise(AppConfig);
+ expect(Option.isSome(result.gremlin.endpoint)).toBe(true);
+ expect(result.gremlin.endpoint).toEqual(
+ Option.some({ host: 'localhost', port: 8182, traversalSource: 'g' })
+ );
expect(result).toMatchObject({
gremlin: {
- host: 'localhost',
- port: 8182,
- traversalSource: 'g',
useSSL: false,
idleTimeout: 300,
},
@@ -89,11 +90,11 @@ describe('Effect-based Configuration Management', () => {
const result = await Effect.runPromise(AppConfig);
+ expect(result.gremlin.endpoint).toEqual(
+ Option.some({ host: 'localhost', port: 8182, traversalSource: 'g' })
+ );
expect(result).toMatchObject({
gremlin: {
- host: 'localhost',
- port: 8182,
- traversalSource: 'g',
useSSL: false,
idleTimeout: 300,
},
@@ -110,10 +111,12 @@ describe('Effect-based Configuration Management', () => {
});
});
- it('should fail when required GREMLIN_MCP_ENDPOINT is missing', async () => {
+ it('should succeed with no GREMLIN_MCP_ENDPOINT (offline mode)', async () => {
delete process.env.GREMLIN_MCP_ENDPOINT;
- await expect(Effect.runPromise(AppConfig)).rejects.toThrow();
+ const result = await Effect.runPromise(AppConfig);
+
+ expect(result.gremlin.endpoint).toEqual(Option.none());
});
it('should parse boolean values correctly', async () => {
@@ -136,9 +139,9 @@ describe('Effect-based Configuration Management', () => {
const result = await Effect.runPromise(AppConfig);
- expect(result.gremlin.host).toBe('localhost');
- expect(result.gremlin.port).toBe(8182);
- expect(result.gremlin.traversalSource).toBe('custom');
+ expect(result.gremlin.endpoint).toEqual(
+ Option.some({ host: 'localhost', port: 8182, traversalSource: 'custom' })
+ );
});
it('should parse comma-separated denylist', async () => {
@@ -235,9 +238,7 @@ describe('Effect-based Configuration Management', () => {
const result = await Effect.runPromise(AppConfig);
// Check all required fields are present
- expect(result.gremlin.host).toBeDefined();
- expect(result.gremlin.port).toBeDefined();
- expect(result.gremlin.traversalSource).toBeDefined();
+ expect(Option.isSome(result.gremlin.endpoint)).toBe(true);
expect(result.gremlin.useSSL).toBeDefined();
expect(result.gremlin.idleTimeout).toBeDefined();
expect(result.schema.enumDiscoveryEnabled).toBeDefined();
@@ -256,7 +257,9 @@ describe('Effect-based Configuration Management', () => {
const result = await Effect.runPromise(AppConfig);
- expect(result.gremlin.traversalSource).toBe('g');
+ expect(result.gremlin.endpoint).toEqual(
+ Option.some({ host: 'localhost', port: 8182, traversalSource: 'g' })
+ );
expect(result.gremlin.useSSL).toBe(false);
expect(result.gremlin.idleTimeout).toBe(300);
expect(result.schema.enumDiscoveryEnabled).toBe(true);
diff --git a/gremlin-mcp/src/main/javascript/tests/resource-read.integration.test.ts b/gremlin-mcp/src/main/javascript/tests/resource-read.integration.test.ts
new file mode 100644
index 0000000000..153d4377bf
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/tests/resource-read.integration.test.ts
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Effect, Layer, Option } from 'effect';
+import { afterEach, beforeEach, describe, expect, it } from '@jest/globals';
+import { Client } from '@modelcontextprotocol/sdk/client/index.js';
+import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
+import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
+import { registerEffectResourceHandlers } from '../src/handlers/resources';
+import { RESOURCE_URIS } from '../src/constants';
+import type { AppConfigType } from '../src/config';
+import { GremlinService } from '../src/gremlin/service';
+import type { GraphSchema, GremlinQueryResult } from '../src/gremlin/models';
+const makeConfig = (): AppConfigType =>
+ ({
+ gremlin: {
+ endpoint: Option.some({ host: 'localhost', port: 8182, traversalSource: 'g' }),
+ useSSL: false,
+ username: Option.none(),
+ password: Option.none(),
+ idleTimeout: 300,
+ },
+ schema: {
+ enumDiscoveryEnabled: true,
+ enumCardinalityThreshold: 10,
+ enumPropertyDenyList: [],
+ includeSampleValues: false,
+ maxEnumValues: 10,
+ includeCounts: false,
+ },
+ server: { name: 'gremlin-mcp', version: 'test' },
+ logging: { level: 'info', structured: true },
+ }) as unknown as AppConfigType;
+const makeFakeRuntime = (statusResult: 'connected' | 'disconnected' = 'connected') => {
+ const schema: GraphSchema = {
+ vertices: [],
+ edges: [],
+ edge_patterns: [],
+ metadata: {
+ generated_at: new Date().toISOString(),
+ generated_by: 'test',
+ sample_size_per_label: 0,
+ optimization_settings: {
+ include_counts: false,
+ include_sample_values: false,
+ max_enum_values: 10,
+ },
+ },
+ };
+
+ const queryResult: GremlinQueryResult = {
+ results: [],
+ message: 'ok',
+ };
+
+ const fakeService = GremlinService.of({
+ getStatus: Effect.succeed({ status: statusResult }),
+ getSchema: Effect.succeed(schema),
+ getCachedSchema: Effect.succeed(null),
+ refreshSchemaCache: Effect.void,
+ executeQuery: (query: string) => {
+ void query;
+ return Effect.succeed(queryResult);
+ },
+ healthCheck: Effect.succeed({
+ healthy: statusResult === 'connected',
+ details: statusResult === 'connected' ? 'Connected' : 'Connection unavailable',
+ }),
+ });
+ return Effect.runSync(
+ Effect.provide(Effect.runtime<GremlinService>(), Layer.succeed(GremlinService, fakeService))
+ );
+};
+describe('resource read integration', () => {
+ const originalEndpoint = process.env.GREMLIN_MCP_ENDPOINT;
+ beforeEach(() => {
+ process.env.GREMLIN_MCP_ENDPOINT = 'localhost:8182/g';
+ });
+ afterEach(() => {
+ if (typeof originalEndpoint === 'string') {
+ process.env.GREMLIN_MCP_ENDPOINT = originalEndpoint;
+ } else {
+ delete process.env.GREMLIN_MCP_ENDPOINT;
+ }
+ });
+ it('returns correct URI and content for status and schema resource reads', async () => {
+ const server = new McpServer({ name: 'resource-read-test-server', version: '1.0.0' });
+ registerEffectResourceHandlers(server, makeFakeRuntime('connected'), makeConfig());
+ const client = new Client({ name: 'resource-read-test-client', version: '1.0.0' });
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
+ await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
+ try {
+ const status = await client.readResource({ uri: RESOURCE_URIS.STATUS });
+ const schema = await client.readResource({ uri: RESOURCE_URIS.SCHEMA });
+ expect(status.contents[0]?.uri).toBe(RESOURCE_URIS.STATUS);
+ const statusText =
+ status.contents[0] && 'text' in status.contents[0] ? status.contents[0].text : '';
+ expect(statusText).toBe('connected');
+ expect(schema.contents[0]?.uri).toBe(RESOURCE_URIS.SCHEMA);
+ const schemaText =
+ schema.contents[0] && 'text' in schema.contents[0] ? schema.contents[0].text : '';
+ expect(schemaText).toContain('vertices');
+ expect(schemaText).toContain('edges');
+ } finally {
+ await client.close();
+ await server.close();
+ }
+ });
+ it('returns offline content when GREMLIN_MCP_ENDPOINT is not set', async () => {
+ delete process.env.GREMLIN_MCP_ENDPOINT;
+ const server = new McpServer({ name: 'resource-offline-test-server', version: '1.0.0' });
+ registerEffectResourceHandlers(server, makeFakeRuntime('connected'), makeConfig());
+ const client = new Client({ name: 'resource-offline-test-client', version: '1.0.0' });
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
+ await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
+ try {
+ const status = await client.readResource({ uri: RESOURCE_URIS.STATUS });
+ const schema = await client.readResource({ uri: RESOURCE_URIS.SCHEMA });
+ const statusText =
+ status.contents[0] && 'text' in status.contents[0] ? status.contents[0].text : '';
+ expect(statusText).toBe('disconnected - configure an endpoint');
+ const schemaText =
+ schema.contents[0] && 'text' in schema.contents[0] ? schema.contents[0].text : '';
+ expect(schemaText).toContain('Configure `GREMLIN_MCP_ENDPOINT`');
+ } finally {
+ await client.close();
+ await server.close();
+ }
+ });
+});
diff --git a/gremlin-mcp/src/main/javascript/tests/resources.test.ts b/gremlin-mcp/src/main/javascript/tests/resources.test.ts
new file mode 100644
index 0000000000..a1200e37d4
--- /dev/null
+++ b/gremlin-mcp/src/main/javascript/tests/resources.test.ts
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Option, Runtime } from 'effect';
+import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
+import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
+import { registerEffectResourceHandlers } from '../src/handlers/resources';
+import { RESOURCE_URIS, MIME_TYPES } from '../src/constants';
+import type { GremlinService } from '../src/gremlin/service';
+import type { AppConfigType } from '../src/config';
+
+type ResourceHandler = (
+ uri: URL,
+ extra: unknown
+) => Promise<{
+ contents: Array<{ uri: string; mimeType: string; text: string }>;
+}>;
+
+const createMockServer = () => {
+ const handlers = new Map<string, ResourceHandler>();
+
+ const server = {
+ registerResource: (
+ name: string,
+ _uri: string,
+ _meta: unknown,
+ handler: ResourceHandler
+ ): void => {
+ handlers.set(name, handler);
+ },
+ } as unknown as McpServer;
+
+ return { server, handlers };
+};
+
+describe('resource handler offline behavior', () => {
+ const originalEndpoint = process.env.GREMLIN_MCP_ENDPOINT;
+
+ beforeEach(() => {
+ delete process.env.GREMLIN_MCP_ENDPOINT;
+ });
+
+ afterEach(() => {
+ if (typeof originalEndpoint === 'string') {
+ process.env.GREMLIN_MCP_ENDPOINT = originalEndpoint;
+ } else {
+ delete process.env.GREMLIN_MCP_ENDPOINT;
+ }
+ });
+
+ it('returns offline status and schema when GREMLIN_MCP_ENDPOINT is missing', async () => {
+ const { server, handlers } = createMockServer();
+
+ const config = {
+ gremlin: {
+ // Simulate stale pre-parsed config; env var absence must still force offline resource output.
+ endpoint: Option.some({ host: 'localhost', port: 8182, traversalSource: 'g' }),
+ useSSL: false,
+ username: Option.none(),
+ password: Option.none(),
+ idleTimeout: 300,
+ },
+ schema: {
+ enumDiscoveryEnabled: true,
+ enumCardinalityThreshold: 10,
+ enumPropertyDenyList: [],
+ includeSampleValues: false,
+ maxEnumValues: 10,
+ includeCounts: false,
+ },
+ server: {
+ name: 'gremlin-mcp',
+ version: 'test',
+ },
+ logging: {
+ level: 'info',
+ structured: true,
+ },
+ } as unknown as AppConfigType;
+
+ registerEffectResourceHandlers(
+ server,
+ Runtime.defaultRuntime as Runtime.Runtime<GremlinService>,
+ config
+ );
+
+ const status = await handlers.get('status')!(new URL(RESOURCE_URIS.STATUS), {});
+ const schema = await handlers.get('schema')!(new URL(RESOURCE_URIS.SCHEMA), {});
+
+ expect(status).toEqual({
+ contents: [
+ {
+ uri: RESOURCE_URIS.STATUS,
+ mimeType: MIME_TYPES.TEXT_PLAIN,
+ text: 'disconnected - configure an endpoint',
+ },
+ ],
+ });
+
+ expect(schema).toEqual({
+ contents: [
+ {
+ uri: RESOURCE_URIS.SCHEMA,
+ mimeType: MIME_TYPES.APPLICATION_JSON,
+ text: JSON.stringify(
+ {
+ status: 'disconnected',
+ message: 'Configure `GREMLIN_MCP_ENDPOINT` to enable graph operations.',
+ },
+ null,
+ 2
+ ),
+ },
+ ],
+ });
+ });
+});
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
index ff4d792054..8d15b389a3 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/language/translator/translations.json
@@ -25428,7 +25428,34 @@
]
},
{
- "scenario": "g_mergeEXout_vadasX_optionXonCreate_created_YX_optionXonMatch_created_NX_exists_updated",
+ "scenario": "g_mergeEXlabel_knows_out_vadasX_optionXonCreate_created_YX_optionXonMatch_created_NX_exists_updated_override_prohibited",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\",\"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\",\"Y\")",
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "anonymized": "g.addV(string0).property(string1, string2).as(string3).addV(string0).property(string1, string4).as(string5).addE(string6).from(string3).to(string5).property(string7, string8).addE(string6).from(string5).to(string3).property(string7, string8)",
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").As(\"a\").AddV((string) \"person\").Property(\"name\", \"vadas\").As(\"b\").AddE((string) \"knows\").From(\"a\").To(\"b\").Property(\"created\", \"Y\").AddE((string) \"knows\").From(\"b\").To(\"a\").Property(\"created\", \"Y\")",
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").As(\"a\").AddV(\"person\").Property(\"name\", \"vadas\").As(\"b\").AddE(\"knows\").From(\"a\").To(\"b\").Property(\"created\", \"Y\").AddE(\"knows\").From(\"b\").To(\"a\").Property(\"created\", \"Y\")",
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from_(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from_(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "python": "g.add_v('person').property('name', 'marko').as_('a').add_v('person').property('name', 'vadas').as_('b').add_e('knows').from_('a').to('b').property('created', 'Y').add_e('knows').from_('b').to('a').property('created', 'Y')"
+ },
+ {
+ "original": "g.mergeE(xx1).option(Merge.onCreate,xx2).option(Merge.onMatch,xx3)",
+ "language": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "anonymized": "g.mergeE(map0).option(Merge.onCreate, map1).option(Merge.onMatch, map2)",
+ "dotnet": "g.MergeE((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (IDictionary<object, object>) xx2).Option(Merge.OnMatch, (IDictionary<object, object>) xx3)",
+ "go": "g.MergeE(xx1).Option(gremlingo.Merge.OnCreate, xx2).Option(gremlingo.Merge.OnMatch, xx3)",
+ "groovy": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "java": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "javascript": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "python": "g.merge_e(xx1).option(Merge.on_create, xx2).option(Merge.on_match, xx3)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_mergeEXout_vadasX_optionXonCreate_created_YX_optionXonMatch_created_NX_exists_updated_error",
"traversals": [
{
"original": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\",\"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\",\"Y\")",
@@ -25498,6 +25525,104 @@
}
]
},
+ {
+ "scenario": "g_mergeEXout_vadasX_optionXonCreate_created_YX_optionXonMatch_created_NX_exists_updated_override_prohibited",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\",\"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\",\"Y\")",
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "anonymized": "g.addV(string0).property(string1, string2).as(string3).addV(string0).property(string1, string4).as(string5).addE(string6).from(string3).to(string5).property(string7, string8).addE(string6).from(string5).to(string3).property(string7, string8)",
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").As(\"a\").AddV((string) \"person\").Property(\"name\", \"vadas\").As(\"b\").AddE((string) \"knows\").From(\"a\").To(\"b\").Property(\"created\", \"Y\").AddE((string) \"knows\").From(\"b\").To(\"a\").Property(\"created\", \"Y\")",
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").As(\"a\").AddV(\"person\").Property(\"name\", \"vadas\").As(\"b\").AddE(\"knows\").From(\"a\").To(\"b\").Property(\"created\", \"Y\").AddE(\"knows\").From(\"b\").To(\"a\").Property(\"created\", \"Y\")",
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from_(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from_(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "python": "g.add_v('person').property('name', 'marko').as_('a').add_v('person').property('name', 'vadas').as_('b').add_e('knows').from_('a').to('b').property('created', 'Y').add_e('knows').from_('b').to('a').property('created', 'Y')"
+ },
+ {
+ "original": "g.mergeE(xx1).option(Merge.onCreate,xx2).option(Merge.onMatch,xx3)",
+ "language": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "anonymized": "g.mergeE(map0).option(Merge.onCreate, map1).option(Merge.onMatch, map2)",
+ "dotnet": "g.MergeE((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (IDictionary<object, object>) xx2).Option(Merge.OnMatch, (IDictionary<object, object>) xx3)",
+ "go": "g.MergeE(xx1).Option(gremlingo.Merge.OnCreate, xx2).Option(gremlingo.Merge.OnMatch, xx3)",
+ "groovy": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "java": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "javascript": "g.mergeE(xx1).option(Merge.onCreate, xx2).option(Merge.onMatch, xx3)",
+ "python": "g.merge_e(xx1).option(Merge.on_create, xx2).option(Merge.on_match, xx3)"
+ }
+ ]
+ },
+ {
+ "scenario": "g_withSideEffect_mergeEXout_vadasX_optionXonCreate_created_YX_optionXonMatch_created_NX_exists_updated_dynamic_override_sketchily_allowed",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\",\"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\",\"Y\")",
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "anonymized": "g.addV(string0).property(string1, string2).as(string3).addV(string0).property(string1, string4).as(string5).addE(string6).from(string3).to(string5).property(string7, string8).addE(string6).from(string5).to(string3).property(string7, string8)",
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").As(\"a\").AddV((string) \"person\").Property(\"name\", \"vadas\").As(\"b\").AddE((string) \"knows\").From(\"a\").To(\"b\").Property(\"created\", \"Y\").AddE((string) \"knows\").From(\"b\").To(\"a\").Property(\"created\", \"Y\")",
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").As(\"a\").AddV(\"person\").Property(\"name\", \"vadas\").As(\"b\").AddE(\"knows\").From(\"a\").To(\"b\").Property(\"created\", \"Y\").AddE(\"knows\").From(\"b\").To(\"a\").Property(\"created\", \"Y\")",
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").as(\"a\").addV(\"person\").property(\"name\", \"vadas\").as(\"b\").addE(\"knows\").from_(\"a\").to(\"b\").property(\"created\", \"Y\").addE(\"knows\").from_(\"b\").to(\"a\").property(\"created\", \"Y\")",
+ "python": "g.add_v('person').property('name', 'marko').as_('a').add_v('person').property('name', 'vadas').as_('b').add_e('knows').from_('a').to('b').property('created', 'Y').add_e('knows').from_('b').to('a').property('created', 'Y')"
+ },
+ {
+ "original": "g.mergeE(xx1).option(Merge.onCreate, select(\"sideEffect1\")).option(Merge.onMatch,xx3)",
+ "language": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\")).option(Merge.onMatch, xx3)",
+ "anonymized": "g.mergeE(map0).option(Merge.onCreate, __.select(string0)).option(Merge.onMatch, map1)",
+ "dotnet": "g.MergeE((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (ITraversal) __.Select<object>(\"sideEffect1\")).Option(Merge.OnMatch, (IDictionary<object, object>) xx3)",
+ "go": "g.MergeE(xx1).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select(\"sideEffect1\")).Option(gremlingo.Merge.OnMatch, xx3)",
+ "groovy": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\")).option(Merge.onMatch, xx3)",
+ "java": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\")).option(Merge.onMatch, xx3)",
+ "javascript": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\")).option(Merge.onMatch, xx3)",
+ "python": "g.merge_e(xx1).option(Merge.on_create, __.select('sideEffect1')).option(Merge.on_match, xx3)"
+ },
+ {
+ "original": "g.V()",
+ "language": "g.V()",
+ "anonymized": "g.V()",
+ "dotnet": "g.V()",
+ "go": "g.V()",
+ "groovy": "g.V()",
+ "java": "g.V()",
+ "javascript": "g.V()",
+ "python": "g.V()"
+ },
+ {
+ "original": "g.E()",
+ "language": "g.E()",
+ "anonymized": "g.E()",
+ "dotnet": "g.E()",
+ "go": "g.E()",
+ "groovy": "g.E()",
+ "java": "g.E()",
+ "javascript": "g.E()",
+ "python": "g.E()"
+ },
+ {
+ "original": "g.E().hasLabel(\"knows\").has(\"created\",\"Y\")",
+ "language": "g.E().hasLabel(\"knows\").has(\"created\", \"Y\")",
+ "anonymized": "g.E().hasLabel(string0).has(string1, string2)",
+ "dotnet": "g.E().HasLabel(\"knows\").Has(\"created\", \"Y\")",
+ "go": "g.E().HasLabel(\"knows\").Has(\"created\", \"Y\")",
+ "groovy": "g.E().hasLabel(\"knows\").has(\"created\", \"Y\")",
+ "java": "g.E().hasLabel(\"knows\").has(\"created\", \"Y\")",
+ "javascript": "g.E().hasLabel(\"knows\").has(\"created\", \"Y\")",
+ "python": "g.E().has_label('knows').has('created', 'Y')"
+ },
+ {
+ "original": "g.E().hasLabel(\"knows\").has(\"created\",\"N\").outV().has(\"name\",\"vadas\")",
+ "language": "g.E().hasLabel(\"knows\").has(\"created\", \"N\").outV().has(\"name\", \"vadas\")",
+ "anonymized": "g.E().hasLabel(string0).has(string1, string2).outV().has(string3, string4)",
+ "dotnet": "g.E().HasLabel(\"knows\").Has(\"created\", \"N\").OutV().Has(\"name\", \"vadas\")",
+ "go": "g.E().HasLabel(\"knows\").Has(\"created\", \"N\").OutV().Has(\"name\", \"vadas\")",
+ "groovy": "g.E().hasLabel(\"knows\").has(\"created\", \"N\").outV().has(\"name\", \"vadas\")",
+ "java": "g.E().hasLabel(\"knows\").has(\"created\", \"N\").outV().has(\"name\", \"vadas\")",
+ "javascript": "g.E().hasLabel(\"knows\").has(\"created\", \"N\").outV().has(\"name\", \"vadas\")",
+ "python": "g.E().has_label('knows').has('created', 'N').out_v().has('name', 'vadas')"
+ }
+ ]
+ },
{
"scenario": "g_V_hasXperson_name_marko_X_mergeEXlabel_self_out_vadas1_in_vadas1X",
"traversals": [
@@ -26305,6 +26430,33 @@
}
]
},
+ {
+ "scenario": "g_withSideEffect_withSideEffect_mergeE_outV_dynamic_override_prohibited",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "anonymized": "g.addV(string0).property(string1, string2).addV(string0).property(string1, string3)",
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").AddV((string) \"person\").Property(\"name\", \"vadas\")",
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").AddV(\"person\").Property(\"name\", \"vadas\")",
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "python": "g.add_v('person').property('name', 'marko').add_v('person').property('name', 'vadas')"
+ },
+ {
+ "original": "g.mergeE(xx1).option(onCreate, select(\"sideEffect1\"))",
+ "language": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "anonymized": "g.mergeE(map0).option(Merge.onCreate, __.select(string0))",
+ "dotnet": "g.MergeE((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (ITraversal) __.Select<object>(\"sideEffect1\"))",
+ "go": "g.MergeE(xx1).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select(\"sideEffect1\"))",
+ "groovy": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "java": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "javascript": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "python": "g.merge_e(xx1).option(Merge.on_create, __.select('sideEffect1'))"
+ }
+ ]
+ },
{
"scenario": "g_mergeE_inV_override_prohibited",
"traversals": [
@@ -26332,6 +26484,33 @@
}
]
},
+ {
+ "scenario": "g_withSideEffect_mergeE_inV_dynamic_override_prohibited",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "anonymized": "g.addV(string0).property(string1, string2).addV(string0).property(string1, string3)",
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").AddV((string) \"person\").Property(\"name\", \"vadas\")",
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").AddV(\"person\").Property(\"name\", \"vadas\")",
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "python": "g.add_v('person').property('name', 'marko').add_v('person').property('name', 'vadas')"
+ },
+ {
+ "original": "g.mergeE(xx1).option(onCreate, select(\"sideEffect1\"))",
+ "language": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "anonymized": "g.mergeE(map0).option(Merge.onCreate, __.select(string0))",
+ "dotnet": "g.MergeE((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (ITraversal) __.Select<object>(\"sideEffect1\"))",
+ "go": "g.MergeE(xx1).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select(\"sideEffect1\"))",
+ "groovy": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "java": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "javascript": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "python": "g.merge_e(xx1).option(Merge.on_create, __.select('sideEffect1'))"
+ }
+ ]
+ },
{
"scenario": "g_mergeE_label_override_prohibited",
"traversals": [
@@ -26359,6 +26538,33 @@
}
]
},
+ {
+ "scenario": "g_mergeE_label_dynamic_override_prohibited",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "anonymized": "g.addV(string0).property(string1, string2).addV(string0).property(string1, string3)",
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").AddV((string) \"person\").Property(\"name\", \"vadas\")",
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").AddV(\"person\").Property(\"name\", \"vadas\")",
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "python": "g.add_v('person').property('name', 'marko').add_v('person').property('name', 'vadas')"
+ },
+ {
+ "original": "g.mergeE(xx1).option(onCreate, select(\"sideEffect1\"))",
+ "language": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "anonymized": "g.mergeE(map0).option(Merge.onCreate, __.select(string0))",
+ "dotnet": "g.MergeE((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (ITraversal) __.Select<object>(\"sideEffect1\"))",
+ "go": "g.MergeE(xx1).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select(\"sideEffect1\"))",
+ "groovy": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "java": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "javascript": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "python": "g.merge_e(xx1).option(Merge.on_create, __.select('sideEffect1'))"
+ }
+ ]
+ },
{
"scenario": "g_mergeE_id_override_prohibited",
"traversals": [
@@ -26386,6 +26592,33 @@
}
]
},
+ {
+ "scenario": "g_withSideEffect_mergeE_id_dynamic_override_prohibited",
+ "traversals": [
+ {
+ "original": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "language": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "anonymized": "g.addV(string0).property(string1, string2).addV(string0).property(string1, string3)",
+ "dotnet": "g.AddV((string) \"person\").Property(\"name\", \"marko\").AddV((string) \"person\").Property(\"name\", \"vadas\")",
+ "go": "g.AddV(\"person\").Property(\"name\", \"marko\").AddV(\"person\").Property(\"name\", \"vadas\")",
+ "groovy": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "java": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "javascript": "g.addV(\"person\").property(\"name\", \"marko\").addV(\"person\").property(\"name\", \"vadas\")",
+ "python": "g.add_v('person').property('name', 'marko').add_v('person').property('name', 'vadas')"
+ },
+ {
+ "original": "g.mergeE(xx1).option(onCreate, select(\"sideEffect1\"))",
+ "language": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "anonymized": "g.mergeE(map0).option(Merge.onCreate, __.select(string0))",
+ "dotnet": "g.MergeE((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (ITraversal) __.Select<object>(\"sideEffect1\"))",
+ "go": "g.MergeE(xx1).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select(\"sideEffect1\"))",
+ "groovy": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "java": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "javascript": "g.mergeE(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "python": "g.merge_e(xx1).option(Merge.on_create, __.select('sideEffect1'))"
+ }
+ ]
+ },
{
"scenario": "g_mergeV_mergeE_combination_new_vertices",
"traversals": [
@@ -28578,6 +28811,22 @@
}
]
},
+ {
+ "scenario": "g_withSideEffect_mergeV_label_dynamic_override_prohibited",
+ "traversals": [
+ {
+ "original": "g.mergeV(xx1).option(onCreate, select('sideEffect1'))",
+ "language": "g.mergeV(xx1).option(Merge.onCreate, __.select('sideEffect1'))",
+ "anonymized": "g.mergeV(map0).option(Merge.onCreate, __.select(string0))",
+ "dotnet": "g.MergeV((IDictionary<object, object>) xx1).Option(Merge.OnCreate, (ITraversal) __.Select<object>(\"sideEffect1\"))",
+ "go": "g.MergeV(xx1).Option(gremlingo.Merge.OnCreate, gremlingo.T__.Select(\"sideEffect1\"))",
+ "groovy": "g.mergeV(xx1).option(Merge.onCreate, __.select('sideEffect1'))",
+ "java": "g.mergeV(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "javascript": "g.mergeV(xx1).option(Merge.onCreate, __.select(\"sideEffect1\"))",
+ "python": "g.merge_v(xx1).option(Merge.on_create, __.select('sideEffect1'))"
+ }
+ ]
+ },
{
"scenario": "g_mergeV_id_override_prohibited",
"traversals": [
(tinkerpop) 03/03: Added docs for gremlin-mcp and javascript translator
Posted by sp...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch js-translator
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 8f32db22948453fde5a1fa47c91f695adc092433
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Fri Mar 13 18:17:52 2026 -0400
Added docs for gremlin-mcp and javascript translator
---
CHANGELOG.asciidoc | 3 ++
docs/src/reference/gremlin-applications.asciidoc | 40 +++++++++++++++++++--
docs/src/upgrade/release-4.x.x.asciidoc | 46 ++++++++++++++++++++++++
gremlin-mcp/src/main/javascript/README.md | 20 ++++++++++-
4 files changed, 106 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 8163211650..679792f59d 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -23,6 +23,9 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
[[release-4-0-0]]
=== TinkerPop 4.0.0 (NOT OFFICIALLY RELEASED YET)
+* Added grammar-based `Translator` for `gremlin-javascript` supporting translation to JavaScript, Python, Go, .NET, Java, Groovy, canonical, and anonymized output.
+* Added `translate_gremlin_query` tool to `gremlin-mcp` that translates Gremlin queries to a target language variant, with optional LLM-assisted normalization via MCP sampling for non-canonical input.
+* Modified `gremlin-mcp` to support offline mode where utility tools (translate, format) remain available without a configured `GREMLIN_MCP_ENDPOINT`.
* Added `__contains__` and `keys()` to `Element` in `gremlin-python`.
* Added `subgraph()` support for `gremlin-python` so that results are stored in a detached `Graph` object.
* Modified grammar to make `discard()` usage more consistent as a filter step where it can now be used to chain additional traversal steps and be used anonymously.
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index d72a63c07c..eada1a5120 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -2351,9 +2351,12 @@ input schema, and a result schema. When connected to a Gremlin MCP server, the a
* Inspect the server’s health and connection to a Gremlin data source
* Discover the graph’s schema (labels, properties, relationships, counts)
* Execute Gremlin traversals
+* Translate Gremlin queries between language variants
+* Format Gremlin queries for readability
The Gremlin MCP server sits alongside Gremlin Server (or any TinkerPop‑compatible endpoint) and forwards tool calls to
-the graph via standard Gremlin traversals.
+the graph via standard Gremlin traversals. The translation and formatting tools are utility tools that work
+independently and do not require a graph connection.
IMPORTANT: This MCP server is designed for development and trusted environments.
@@ -2380,6 +2383,7 @@ The Gremlin MCP server exposes these tools:
properties may be surfaced as enums to encourage valid values in queries.
* `run_gremlin_query` — Executes an arbitrary Gremlin traversal and returns JSON results.
* `refresh_schema_cache` — Forces schema discovery to run again when the graph has changed.
+* `translate_gremlin_query` — Translates a Gremlin query to a target language variant with optional normalization.
* `format_gremlin_query` — Formats a Gremlin query using gremlint.
==== Schema discovery
@@ -2437,6 +2441,38 @@ g.V().
limit(1).fold())
----
+==== Translating traversals
+
+The `translate_gremlin_query` tool translates a Gremlin query from one language variant to another. Supported
+targets are: `canonical`, `javascript`, `python`, `go`, `dotnet`, `java`, `groovy`, and `anonymized`. The
+`canonical` target produces gremlin-language ANTLR format with normalized whitespace and explicit enum names,
+which is useful for validating or standardizing queries before further processing.
+
+The optional `source` parameter controls how the input is pre-processed before translation:
+
+* When omitted or set to `auto` (the default), the server applies mechanical normalization (stripping
+ language-specific prefixes, correcting step casing) and then requests LLM normalization from the MCP client
+ via MCP sampling. This handles input from any dialect without the caller needing to know the source language.
+ If the MCP client does not support sampling, the LLM step is skipped and a `warning` field is included in
+ the response to indicate that the result is based on mechanical normalization only.
+* When set to `canonical`, normalization is skipped entirely and the input is passed directly to the translator.
+ This is the most efficient path when the input is known to be in canonical gremlin-language ANTLR format.
+
+For example, a user could supply this prompt to the assistant:
+
+[source,text]
+----
+Translate this Go traversal to Groovy:
+gremlingo.T__.V().Has("name", "Alice").Out("knows").Values("name")
+----
+
+And the assistant would call `translate_gremlin_query` with `target: "groovy"` and receive:
+
+[source,groovy]
+----
+g.V().has('name', 'Alice').out('knows').values('name')
+----
+
==== Executing traversals
When the assistant needs to answer a question, a common sequence is:
@@ -2461,7 +2497,7 @@ endpoint the server should use.
Basic connection settings:
-* `GREMLIN_MCP_ENDPOINT` — `host:port` or `host:port/traversal_source` for the target Gremlin Server or compatible endpoint (default traversal source: `g`)
+* `GREMLIN_MCP_ENDPOINT` — `host:port` or `host:port/traversal_source` for the target Gremlin Server or compatible endpoint (default traversal source: `g`). Optional — when not set, graph tools are not registered but `translate_gremlin_query` and `format_gremlin_query` remain available.
* `GREMLIN_MCP_USE_SSL` — set to `true` when TLS is required by the endpoint (default: `false`)
* `GREMLIN_MCP_USERNAME` / `GREMLIN_PASSWORD` — credentials when authentication is enabled (optional)
* `GREMLIN_MCP_IDLE_TIMEOUT` — idle connection timeout in seconds (default: `300`)
diff --git a/docs/src/upgrade/release-4.x.x.asciidoc b/docs/src/upgrade/release-4.x.x.asciidoc
index 6033d969c3..6d0123b096 100644
--- a/docs/src/upgrade/release-4.x.x.asciidoc
+++ b/docs/src/upgrade/release-4.x.x.asciidoc
@@ -30,6 +30,52 @@ complete list of all the modifications that are part of this release.
=== Upgrading for Users
+==== Gremlin MCP Server
+
+===== Gremlin Query Translation
+
+A `translate_gremlin_query` tool is now available that translates a Gremlin query into a target language variant.
+Supported targets are `canonical`, `javascript`, `python`, `go`, `dotnet`, `java`, `groovy`, and `anonymized`.
+
+The optional `source` parameter describes the dialect of the input. When omitted or set to `auto`, the server
+normalizes the input before translating — first by applying mechanical transformations (stripping language-specific
+prefixes, correcting step casing, etc.) and then by requesting LLM normalization from the MCP client via MCP
+sampling. If the MCP client does not support sampling, the LLM step is skipped gracefully and a warning is included
+in the response. Set `source` to `canonical` to bypass normalization entirely when the input is already in canonical
+gremlin-language ANTLR format.
+
+Some example prompts that will invoke this tool:
+
+[source,text]
+----
+Translate g.V().has('name','Alice').out('knows').values('name') to Python.
+----
+
+[source,text]
+----
+Convert this Go Gremlin traversal to Groovy:
+gremlingo.T__.V().Has("name", "Alice").Out("knows").Values("name")
+----
+
+[source,text]
+----
+I have some Java Gremlin code. Translate it to canonical format so I can review it:
+g.V().has("name", "Alice").out("knows").values("name")
+----
+
+===== Offline Mode
+
+`GREMLIN_MCP_ENDPOINT` is no longer required to start the server. When no endpoint is configured, graph tools
+(`get_graph_status`, `get_graph_schema`, `run_gremlin_query`) are not registered, but the utility tools
+(`translate_gremlin_query`, `format_gremlin_query`) remain fully available. This makes it possible to use the
+Gremlin MCP Server purely as a translation and formatting aid without any graph database:
+
+[source,text]
+----
+Format this Gremlin query for readability:
+g.V().has('name','Alice').out('knows').out('knows').where(neq('Alice')).values('name').dedup()
+----
+
==== SLF4j 2.x
TinkerPop has generally upgraded to SLF4j 2.x which brings with it some important changes to log initialization which
diff --git a/gremlin-mcp/src/main/javascript/README.md b/gremlin-mcp/src/main/javascript/README.md
index aa2a6659d3..d3741be8ae 100644
--- a/gremlin-mcp/src/main/javascript/README.md
+++ b/gremlin-mcp/src/main/javascript/README.md
@@ -48,8 +48,26 @@ Your AI assistant gets access to these powerful tools:
| 📋 **get_graph_schema** | Schema Discovery | Get complete graph structure with vertices and edges |
| ⚡ **run_gremlin_query** | Query Execution | Execute any Gremlin traversal query with full syntax support |
| 🔄 **refresh_schema_cache** | Cache Management | Force immediate refresh of cached schema information |
+| 🔄 **translate_gremlin_query** | Translation | Translate a Gremlin query to a target language variant |
| 👌 **format_gremlin_query** | Query Formatting | Format a Gremlin query string using gremlint |
+### Gremlin Query Translation
+
+The `translate_gremlin_query` tool translates a Gremlin query to a target language variant. Supported targets
+are: `canonical`, `javascript`, `python`, `go`, `dotnet`, `java`, `groovy`, and `anonymized`.
+
+The optional `source` parameter describes the dialect of the input. When omitted or set to `auto` (the default),
+the server first applies mechanical normalization and then requests LLM normalization from the MCP client via MCP
+sampling before translating. If the MCP client does not support sampling, the LLM step is skipped and a warning
+is included in the response. Set `source` to `canonical` to skip normalization entirely when the input is already
+in canonical gremlin-language ANTLR format.
+
+### Offline Mode
+
+`GREMLIN_MCP_ENDPOINT` is optional. When not set, graph tools (`get_graph_status`, `get_graph_schema`,
+`run_gremlin_query`, `refresh_schema_cache`) are not registered, but `translate_gremlin_query` and
+`format_gremlin_query` remain fully available.
+
## 🚀 Quick Setup
### Step 1: Install
@@ -333,7 +351,7 @@ This intelligent enum discovery transforms how AI agents interact with your grap
### Basic Configuration
```bash
-# Required
+# Optional - when not set, graph tools are unavailable but translate and format tools remain active
GREMLIN_MCP_ENDPOINT="localhost:8182"
# Optional