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

Cole-Greer pushed a commit to branch simplePDT
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 3ec227cc9704564ffe98109c1a0a38f00bac14c3
Author: Cole Greer <[email protected]>
AuthorDate: Wed Jun 24 13:14:29 2026 -0700

    Add core PrimitiveProviderDefinedType + GraphBinary serializer (0xF1)
    
    Introduces the core value type for PrimitivePDT and its GraphBinary
    serialization, mirroring the composite ProviderDefinedType.
    
    - PrimitiveProviderDefinedType: immutable (String name, String value).
      name non-null/non-empty; value non-null with empty string allowed and
      null rejected; equals/hashCode on (name, value); toString 
pdt[name](value);
      transient withHydrated/getHydrated for symmetry. The value is opaque and
      is never parsed or normalized.
    - PrimitiveProviderDefinedTypeSerializer: SimpleTypeSerializer over
      DataType.PRIMITIVE_PDT writing/reading two fully-qualified Strings
      ({name}{value}).
    - DataType: add PRIMITIVE_PDT(0xF1).
    - TypeSerializerRegistry: register PrimitiveProviderDefinedType ->
      PrimitiveProviderDefinedTypeSerializer.
    
    Adapter/registry hydration, reader/writer dehydration dispatch, GraphSON,
    grammar, and GLVs are deferred to later beads.
    
    Tests: PrimitiveProviderDefinedTypeTest (validation, 
equals/hashCode/toString)
    and PrimitiveProviderDefinedTypeSerializerTest (round-trip incl. 
opaque-value
    fidelity: leading zeros, large and non-numeric values).
    
    tinkerpop-2gy.2
    
    Assisted-by: Kiro:claude-opus-4.8
---
 .../gremlin/structure/io/binary/DataType.java      |   1 +
 .../io/binary/TypeSerializerRegistry.java          |   5 +-
 .../PrimitiveProviderDefinedTypeSerializer.java    |  47 +++++++++
 .../io/pdt/PrimitiveProviderDefinedType.java       |  82 ++++++++++++++++
 .../io/pdt/PrimitiveProviderDefinedTypeTest.java   |  99 +++++++++++++++++++
 ...PrimitiveProviderDefinedTypeSerializerTest.java | 106 +++++++++++++++++++++
 6 files changed, 339 insertions(+), 1 deletion(-)

diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
index 6ca99db840..fa6115cc76 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/DataType.java
@@ -59,6 +59,7 @@ public enum DataType {
     DURATION(0X81),
 
     COMPOSITE_PDT(0xF0),
+    PRIMITIVE_PDT(0xF1),
 
     MARKER(0XFD),
     UNSPECIFIED_NULL(0XFE);
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
index c0a3234aac..549cb2ccc0 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/TypeSerializerRegistry.java
@@ -33,6 +33,7 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.io.pdt.ProviderDefined;
 import org.apache.tinkerpop.gremlin.structure.io.pdt.ProviderDefinedType;
+import 
org.apache.tinkerpop.gremlin.structure.io.pdt.PrimitiveProviderDefinedType;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.BigDecimalSerializer;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.BigIntegerSerializer;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.BulkSetSerializer;
@@ -49,6 +50,7 @@ import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.DateTimeSerializer
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.PathSerializer;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.PropertySerializer;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.ProviderDefinedTypeSerializer;
+import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.PrimitiveProviderDefinedTypeSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.SetSerializer;
 import 
org.apache.tinkerpop.gremlin.structure.io.binary.types.SingleTypeSerializer;
 import org.apache.tinkerpop.gremlin.structure.io.binary.types.StringSerializer;
@@ -121,7 +123,8 @@ public class TypeSerializerRegistry {
             new RegistryEntry<>(Character.class, new CharSerializer()),
             new RegistryEntry<>(Duration.class, new DurationSerializer()),
             new RegistryEntry<>(OffsetDateTime.class, new 
DateTimeSerializer()),
-            new RegistryEntry<>(ProviderDefinedType.class, new 
ProviderDefinedTypeSerializer())
+            new RegistryEntry<>(ProviderDefinedType.class, new 
ProviderDefinedTypeSerializer()),
+            new RegistryEntry<>(PrimitiveProviderDefinedType.class, new 
PrimitiveProviderDefinedTypeSerializer())
     };
 
     public static final TypeSerializerRegistry INSTANCE = build().create();
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/PrimitiveProviderDefinedTypeSerializer.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/PrimitiveProviderDefinedTypeSerializer.java
new file mode 100644
index 0000000000..9bb6b1f646
--- /dev/null
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/binary/types/PrimitiveProviderDefinedTypeSerializer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.structure.io.binary.types;
+
+import org.apache.tinkerpop.gremlin.structure.io.Buffer;
+import org.apache.tinkerpop.gremlin.structure.io.binary.DataType;
+import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader;
+import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter;
+import 
org.apache.tinkerpop.gremlin.structure.io.pdt.PrimitiveProviderDefinedType;
+
+import java.io.IOException;
+
+public class PrimitiveProviderDefinedTypeSerializer extends 
SimpleTypeSerializer<PrimitiveProviderDefinedType> {
+
+    public PrimitiveProviderDefinedTypeSerializer() {
+        super(DataType.PRIMITIVE_PDT);
+    }
+
+    @Override
+    protected PrimitiveProviderDefinedType readValue(final Buffer buffer, 
final GraphBinaryReader context) throws IOException {
+        final String name = context.read(buffer);
+        final String value = context.read(buffer);
+        return new PrimitiveProviderDefinedType(name, value);
+    }
+
+    @Override
+    protected void writeValue(final PrimitiveProviderDefinedType value, final 
Buffer buffer, final GraphBinaryWriter context) throws IOException {
+        context.write(value.getName(), buffer);
+        context.write(value.getValue(), buffer);
+    }
+}
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/pdt/PrimitiveProviderDefinedType.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/pdt/PrimitiveProviderDefinedType.java
new file mode 100644
index 0000000000..dbf3938ac2
--- /dev/null
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/pdt/PrimitiveProviderDefinedType.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.structure.io.pdt;
+
+import java.util.Objects;
+
+/**
+ * An immutable representation of a primitive provider-defined type consisting 
of a name and an opaque string value.
+ */
+public final class PrimitiveProviderDefinedType {
+
+    private final String name;
+    private final String value;
+    private transient Object hydrated;
+
+    public PrimitiveProviderDefinedType(final String name, final String value) 
{
+        if (name == null || name.isEmpty())
+            throw new IllegalArgumentException("name cannot be null or empty");
+        if (value == null)
+            throw new IllegalArgumentException("value cannot be null");
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Returns a copy of this primitive PDT with the hydrated object attached.
+     */
+    public PrimitiveProviderDefinedType withHydrated(final Object hydrated) {
+        final PrimitiveProviderDefinedType copy = new 
PrimitiveProviderDefinedType(this.name, this.value);
+        copy.hydrated = hydrated;
+        return copy;
+    }
+
+    /**
+     * Returns the hydrated object if set, or {@code null}.
+     */
+    public Object getHydrated() {
+        return hydrated;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PrimitiveProviderDefinedType)) return false;
+        final PrimitiveProviderDefinedType that = 
(PrimitiveProviderDefinedType) o;
+        return name.equals(that.name) && value.equals(that.value);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, value);
+    }
+
+    @Override
+    public String toString() {
+        return "pdt[" + name + "](" + value + ")";
+    }
+}
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/pdt/PrimitiveProviderDefinedTypeTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/pdt/PrimitiveProviderDefinedTypeTest.java
new file mode 100644
index 0000000000..dcde0f6452
--- /dev/null
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/pdt/PrimitiveProviderDefinedTypeTest.java
@@ -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.
+ */
+package org.apache.tinkerpop.gremlin.structure.io.pdt;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+
+public class PrimitiveProviderDefinedTypeTest {
+
+    @Test
+    public void shouldConstructWithNameAndValue() {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Uint32", "42");
+        assertEquals("Uint32", pdt.getName());
+        assertEquals("42", pdt.getValue());
+    }
+
+    @Test
+    public void shouldAllowEmptyStringValue() {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Empty", "");
+        assertEquals("", pdt.getValue());
+    }
+
+    @Test
+    public void shouldThrowOnNullName() {
+        assertThrows(IllegalArgumentException.class, () -> new 
PrimitiveProviderDefinedType(null, "v"));
+    }
+
+    @Test
+    public void shouldThrowOnEmptyName() {
+        assertThrows(IllegalArgumentException.class, () -> new 
PrimitiveProviderDefinedType("", "v"));
+    }
+
+    @Test
+    public void shouldThrowOnNullValue() {
+        assertThrows(IllegalArgumentException.class, () -> new 
PrimitiveProviderDefinedType("Name", null));
+    }
+
+    @Test
+    public void shouldHaveCorrectEquals() {
+        final PrimitiveProviderDefinedType a = new 
PrimitiveProviderDefinedType("Uint32", "007");
+        final PrimitiveProviderDefinedType b = new 
PrimitiveProviderDefinedType("Uint32", "007");
+        assertEquals(a, b);
+        assertEquals(a.hashCode(), b.hashCode());
+    }
+
+    @Test
+    public void shouldNotEqualDifferentName() {
+        final PrimitiveProviderDefinedType a = new 
PrimitiveProviderDefinedType("Uint32", "42");
+        final PrimitiveProviderDefinedType b = new 
PrimitiveProviderDefinedType("Int64", "42");
+        assertNotEquals(a, b);
+    }
+
+    @Test
+    public void shouldNotEqualDifferentValue() {
+        final PrimitiveProviderDefinedType a = new 
PrimitiveProviderDefinedType("Uint32", "42");
+        final PrimitiveProviderDefinedType b = new 
PrimitiveProviderDefinedType("Uint32", "43");
+        assertNotEquals(a, b);
+    }
+
+    @Test
+    public void shouldHaveCorrectToString() {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Uint32", "42");
+        assertEquals("pdt[Uint32](42)", pdt.toString());
+    }
+
+    @Test
+    public void shouldSupportHydratedObject() {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Uint32", "42");
+        assertNull(pdt.getHydrated());
+
+        final Object hydrated = Long.valueOf(42L);
+        final PrimitiveProviderDefinedType withHydrated = 
pdt.withHydrated(hydrated);
+        assertEquals(hydrated, withHydrated.getHydrated());
+        // original is unchanged
+        assertNull(pdt.getHydrated());
+        // logical equality is not affected by hydration
+        assertEquals(pdt, withHydrated);
+    }
+}
diff --git 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/PrimitiveProviderDefinedTypeSerializerTest.java
 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/PrimitiveProviderDefinedTypeSerializerTest.java
new file mode 100644
index 0000000000..1cc9d216f5
--- /dev/null
+++ 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/util/ser/binary/types/PrimitiveProviderDefinedTypeSerializerTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+package org.apache.tinkerpop.gremlin.util.ser.binary.types;
+
+import io.netty.buffer.ByteBufAllocator;
+import org.apache.tinkerpop.gremlin.structure.io.Buffer;
+import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryReader;
+import org.apache.tinkerpop.gremlin.structure.io.binary.GraphBinaryWriter;
+import 
org.apache.tinkerpop.gremlin.structure.io.pdt.PrimitiveProviderDefinedType;
+import org.apache.tinkerpop.gremlin.util.ser.NettyBufferFactory;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class PrimitiveProviderDefinedTypeSerializerTest {
+
+    private static final GraphBinaryReader reader = new GraphBinaryReader();
+    private static final GraphBinaryWriter writer = new GraphBinaryWriter();
+    private static final ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
+    private static final NettyBufferFactory bufferFactory = new 
NettyBufferFactory();
+
+    private Buffer writeAndRead(final Object value) throws IOException {
+        final Buffer buffer = bufferFactory.create(allocator.buffer());
+        writer.write(value, buffer);
+        buffer.readerIndex(0);
+        return buffer;
+    }
+
+    @Test
+    public void shouldRoundTripSimplePrimitivePdt() throws IOException {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Uint32", "42");
+
+        final Buffer buffer = writeAndRead(pdt);
+        final PrimitiveProviderDefinedType result = reader.read(buffer);
+
+        assertEquals(pdt, result);
+    }
+
+    @Test
+    public void shouldRoundTripEmptyValue() throws IOException {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Empty", "");
+
+        final Buffer buffer = writeAndRead(pdt);
+        final PrimitiveProviderDefinedType result = reader.read(buffer);
+
+        assertEquals(pdt, result);
+    }
+
+    @Test
+    public void shouldPreserveLeadingZeros() throws IOException {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Uint32", "007");
+
+        final Buffer buffer = writeAndRead(pdt);
+        final PrimitiveProviderDefinedType result = reader.read(buffer);
+
+        assertEquals("007", result.getValue());
+    }
+
+    @Test
+    public void shouldPreserveLargeValues() throws IOException {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("Uint32", "4294967295");
+
+        final Buffer buffer = writeAndRead(pdt);
+        final PrimitiveProviderDefinedType result = reader.read(buffer);
+
+        assertEquals("4294967295", result.getValue());
+    }
+
+    @Test
+    public void shouldPreserveNonNumericStrings() throws IOException {
+        final PrimitiveProviderDefinedType pdt = new 
PrimitiveProviderDefinedType("TinkerId", "abc-def-123");
+
+        final Buffer buffer = writeAndRead(pdt);
+        final PrimitiveProviderDefinedType result = reader.read(buffer);
+
+        assertEquals("abc-def-123", result.getValue());
+    }
+
+    @Test
+    public void shouldHandleNullPrimitivePdt() throws IOException {
+        final Buffer buffer = bufferFactory.create(allocator.buffer());
+        writer.write(null, buffer);
+        buffer.readerIndex(0);
+        final Object result = reader.read(buffer);
+        assertNull(result);
+    }
+}

Reply via email to