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

xiazcy pushed a commit to branch gremlin-go-http
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 11c2feb0c04d1175f816e50c74df8c8e2049e4c4
Author: Yang Xia <[email protected]>
AuthorDate: Fri Feb 21 14:26:08 2025 -0800

    Update Graph Binary serializer to 4.0.0 spec for Go (#3034)
    
    * update graph binary serializer to 4.0.0 spec
---
 gremlin-go/driver/graphBinary.go      | 526 +++++++---------------------------
 gremlin-go/driver/graphBinary_test.go |  29 +-
 gremlin-go/driver/marker.go           |  46 +++
 gremlin-go/driver/serializer.go       |  65 ++---
 4 files changed, 193 insertions(+), 473 deletions(-)

diff --git a/gremlin-go/driver/graphBinary.go b/gremlin-go/driver/graphBinary.go
index 39c6d2f029..5ffc83773d 100644
--- a/gremlin-go/driver/graphBinary.go
+++ b/gremlin-go/driver/graphBinary.go
@@ -38,54 +38,34 @@ type dataType uint8
 
 // dataType defined as constants.
 const (
-       customType            dataType = 0x00
-       intType               dataType = 0x01
-       longType              dataType = 0x02
-       stringType            dataType = 0x03
-       dateType              dataType = 0x04
-       timestampType         dataType = 0x05
-       classType             dataType = 0x06
-       doubleType            dataType = 0x07
-       floatType             dataType = 0x08
-       listType              dataType = 0x09
-       mapType               dataType = 0x0a
-       setType               dataType = 0x0b
-       uuidType              dataType = 0x0c
-       edgeType              dataType = 0x0d
-       pathType              dataType = 0x0e
-       propertyType          dataType = 0x0f
-       vertexType            dataType = 0x11
-       vertexPropertyType    dataType = 0x12
-       barrierType           dataType = 0x13
-       bindingType           dataType = 0x14
-       cardinalityType       dataType = 0x16
-       bytecodeType          dataType = 0x15
-       columnType            dataType = 0x17
-       directionType         dataType = 0x18
-       operatorType          dataType = 0x19
-       orderType             dataType = 0x1a
-       pickType              dataType = 0x1b
-       popType               dataType = 0x1c
-       lambdaType            dataType = 0x1d
-       pType                 dataType = 0x1e
-       scopeType             dataType = 0x1f
-       tType                 dataType = 0x20
-       traverserType         dataType = 0x21
-       bigDecimalType        dataType = 0x22
-       bigIntegerType        dataType = 0x23
-       byteType              dataType = 0x24
-       byteBuffer            dataType = 0x25
-       shortType             dataType = 0x26
-       booleanType           dataType = 0x27
-       textPType             dataType = 0x28
-       traversalStrategyType dataType = 0x29
-       bulkSetType           dataType = 0x2a
-       mergeType             dataType = 0x2e
-       dtType                dataType = 0x2f
-       metricsType           dataType = 0x2c
-       traversalMetricsType  dataType = 0x2d
-       durationType          dataType = 0x81
-       nullType              dataType = 0xFE
+       customType         dataType = 0x00
+       intType            dataType = 0x01
+       longType           dataType = 0x02
+       stringType         dataType = 0x03
+       datetimeType       dataType = 0x04
+       doubleType         dataType = 0x07
+       floatType          dataType = 0x08
+       listType           dataType = 0x09
+       mapType            dataType = 0x0a
+       setType            dataType = 0x0b
+       uuidType           dataType = 0x0c
+       edgeType           dataType = 0x0d
+       pathType           dataType = 0x0e
+       propertyType       dataType = 0x0f
+       vertexType         dataType = 0x11
+       vertexPropertyType dataType = 0x12
+       directionType      dataType = 0x18
+       tType              dataType = 0x20
+       bigDecimalType     dataType = 0x22
+       bigIntegerType     dataType = 0x23
+       byteType           dataType = 0x24
+       byteBuffer         dataType = 0x25
+       shortType          dataType = 0x26
+       booleanType        dataType = 0x27
+       mergeType          dataType = 0x2e
+       durationType       dataType = 0x81
+       markerType         dataType = 0xfd
+       nullType           dataType = 0xFE
 )
 
 var nullBytes = []byte{nullType.getCodeByte(), 0x01}
@@ -191,72 +171,6 @@ func mapWriter(value interface{}, buffer *bytes.Buffer, 
typeSerializer *graphBin
        return buffer.Bytes(), nil
 }
 
-func instructionWriter(instructions []instruction, buffer *bytes.Buffer, 
typeSerializer *graphBinaryTypeSerializer) error {
-       // Write {steps_length}, i.e number of steps.
-       err := binary.Write(buffer, binary.BigEndian, int32(len(instructions)))
-       if err != nil {
-               return err
-       }
-
-       // Write {step_0} to {step_n}.
-       for _, instruction := range instructions {
-               // Write {name} of {step_i}.
-               // Note: {name} follows string writing, therefore write string 
length followed by actual string.
-               _, err = typeSerializer.writeValue(instruction.operator, 
buffer, false)
-               if err != nil {
-                       return err
-               }
-
-               // Write {values_length} of {step_i}.
-               err = binary.Write(buffer, binary.BigEndian, 
int32(len(instruction.arguments)))
-               if err != nil {
-                       return err
-               }
-
-               // Write {values_0} to {values_n}.
-               for _, argument := range instruction.arguments {
-                       _, err = typeSerializer.write(argument, buffer)
-                       if err != nil {
-                               return err
-                       }
-               }
-       }
-       return nil
-}
-
-// Format: {steps_length}{step_0}…{step_n}{sources_length}{source_0}…{source_n}
-// Where:
-//
-//                     {steps_length} is an Int value describing the amount of 
steps.
-//                     {step_i} is composed of 
{name}{values_length}{value_0}…{value_n}, where:
-//          {name} is a String. This is also known as the operator.
-//                     {values_length} is an Int describing the amount values.
-//                     {value_i} is a fully qualified typed value composed of 
{type_code}{type_info}{value_flag}{value} describing the step argument.
-func bytecodeWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
-       var bc Bytecode
-       switch typedVal := value.(type) {
-       case *GraphTraversal:
-               bc = *typedVal.Bytecode
-       case Bytecode:
-               bc = typedVal
-       case *Bytecode:
-               bc = *typedVal
-       default:
-               return nil, newError(err0402BytecodeWriterError)
-       }
-
-       // Write {steps_length} and {step_0} through {step_n}, then 
{sources_length} and {source_0} through {source_n}
-       err := instructionWriter(bc.stepInstructions, buffer, typeSerializer)
-       if err != nil {
-               return nil, err
-       }
-       err = instructionWriter(bc.sourceInstructions, buffer, typeSerializer)
-       if err != nil {
-               return nil, err
-       }
-       return buffer.Bytes(), nil
-}
-
 func stringWriter(value interface{}, buffer *bytes.Buffer, _ 
*graphBinaryTypeSerializer) ([]byte, error) {
        err := binary.Write(buffer, binary.BigEndian, 
int32(len(value.(string))))
        if err != nil {
@@ -366,16 +280,6 @@ func bigDecimalWriter(value interface{}, buffer 
*bytes.Buffer, typeSerializer *g
        return bigIntWriter(v.UnscaledValue, buffer, typeSerializer)
 }
 
-func classWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
-       var v GremlinType
-       if reflect.TypeOf(value).Kind() == reflect.Ptr {
-               v = *(value.(*GremlinType))
-       } else {
-               v = value.(GremlinType)
-       }
-       return stringWriter(v.Fqcn, buffer, typeSerializer)
-}
-
 // Format: {Id}{Label}{properties}
 func vertexWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
        v := value.(*Vertex)
@@ -385,7 +289,7 @@ func vertexWriter(value interface{}, buffer *bytes.Buffer, 
typeSerializer *graph
        }
 
        // Not fully qualified.
-       _, err = typeSerializer.writeValue(v.Label, buffer, false)
+       _, err = typeSerializer.writeValue([1]string{v.Label}, buffer, false)
        if err != nil {
                return nil, err
        }
@@ -403,7 +307,7 @@ func edgeWriter(value interface{}, buffer *bytes.Buffer, 
typeSerializer *graphBi
        }
 
        // Not fully qualified
-       _, err = typeSerializer.writeValue(e.Label, buffer, false)
+       _, err = typeSerializer.writeValue([1]string{e.Label}, buffer, false)
        if err != nil {
                return nil, err
        }
@@ -465,7 +369,7 @@ func vertexPropertyWriter(value interface{}, buffer 
*bytes.Buffer, typeSerialize
        }
 
        // Not fully qualified.
-       _, err = typeSerializer.writeValue(vp.Label, buffer, false)
+       _, err = typeSerializer.writeValue([1]string{vp.Label}, buffer, false)
        if err != nil {
                return nil, err
        }
@@ -502,7 +406,29 @@ func setWriter(value interface{}, buffer *bytes.Buffer, 
typeSerializer *graphBin
 
 func timeWriter(value interface{}, buffer *bytes.Buffer, _ 
*graphBinaryTypeSerializer) ([]byte, error) {
        t := value.(time.Time)
-       err := binary.Write(buffer, binary.BigEndian, t.UnixMilli())
+       err := binary.Write(buffer, binary.BigEndian, int32(t.Year()))
+       if err != nil {
+               return nil, err
+       }
+       err = binary.Write(buffer, binary.BigEndian, byte(t.Month()))
+       if err != nil {
+               return nil, err
+       }
+       err = binary.Write(buffer, binary.BigEndian, byte(t.Day()))
+       if err != nil {
+               return nil, err
+       }
+       // construct time of day in nanoseconds
+       h := t.Hour()
+       m := t.Minute()
+       s := t.Second()
+       ns := (h * 60 * 60 * 1e9) + (m * 60 * 1e9) + (s * 1e9) + t.Nanosecond()
+       err = binary.Write(buffer, binary.BigEndian, int64(ns))
+       if err != nil {
+               return nil, err
+       }
+       _, os := t.Zone()
+       err = binary.Write(buffer, binary.BigEndian, int32(os))
        if err != nil {
                return nil, err
        }
@@ -524,40 +450,15 @@ func durationWriter(value interface{}, buffer 
*bytes.Buffer, _ *graphBinaryTypeS
        return buffer.Bytes(), nil
 }
 
-const (
-       valueFlagNull byte = 1
-       valueFlagNone byte = 0
-)
-
 func enumWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
        _, err := typeSerializer.write(reflect.ValueOf(value).String(), buffer)
        return buffer.Bytes(), err
 }
 
-// Format: {language}{script}{arguments_length}
-func lambdaWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
-       lambda := value.(*Lambda)
-       if lambda.Language == "" {
-               lambda.Language = "gremlin-groovy"
-       }
-       _, err := typeSerializer.writeValue(lambda.Language, buffer, false)
-       if err != nil {
-               return nil, err
-       }
-
-       _, err = typeSerializer.writeValue(lambda.Script, buffer, false)
-       if err != nil {
-               return nil, err
-       }
-
-       // It's hard to know how many parameters there are without extensive 
string parsing.
-       // Instead, we can set -1 which means unknown.
-       err = binary.Write(buffer, binary.BigEndian, int32(-1))
-       if err != nil {
-               return nil, err
-       }
-
-       return buffer.Bytes(), nil
+func markerWriter(value interface{}, buffer *bytes.Buffer, _ 
*graphBinaryTypeSerializer) ([]byte, error) {
+       m := value.(Marker)
+       err := binary.Write(buffer, binary.BigEndian, m.GetValue())
+       return buffer.Bytes(), err
 }
 
 // Format: {strategy_class}{configuration}
@@ -572,84 +473,13 @@ func traversalStrategyWriter(value interface{}, buffer 
*bytes.Buffer, typeSerial
        return mapWriter(ts.configuration, buffer, typeSerializer)
 }
 
-func pWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
-       var v p
-       if reflect.TypeOf(value).Kind() == reflect.Ptr {
-               v = *(value.(*p))
-       } else {
-               v = value.(p)
-       }
-       _, err := typeSerializer.writeValue(v.operator, buffer, false)
-       if err != nil {
-               return nil, err
-       }
-
-       err = binary.Write(buffer, binary.BigEndian, int32(len(v.values)))
-       if err != nil {
-               return nil, err
-       }
-
-       for _, pValue := range v.values {
-               _, err := typeSerializer.write(pValue, buffer)
-               if err != nil {
-                       return nil, err
-               }
-       }
-       return buffer.Bytes(), err
-}
-
-func textPWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
-       var v textP
-       if reflect.TypeOf(value).Kind() == reflect.Ptr {
-               v = *(value.(*textP))
-       } else {
-               v = value.(textP)
-       }
-       _, err := typeSerializer.writeValue(v.operator, buffer, false)
-       if err != nil {
-               return nil, err
-       }
-
-       err = binary.Write(buffer, binary.BigEndian, int32(len(v.values)))
-       if err != nil {
-               return nil, err
-       }
-
-       for _, pValue := range v.values {
-               _, err := typeSerializer.write(pValue, buffer)
-               if err != nil {
-                       return nil, err
-               }
-       }
-       return buffer.Bytes(), err
-}
-
-// Format: {key}{value}
-func bindingWriter(value interface{}, buffer *bytes.Buffer, typeSerializer 
*graphBinaryTypeSerializer) ([]byte, error) {
-       var v Binding
-       if reflect.TypeOf(value).Kind() == reflect.Ptr {
-               v = *(value.(*Binding))
-       } else {
-               v = value.(Binding)
-       }
-
-       // Not fully qualified.
-       _, err := typeSerializer.writeValue(v.Key, buffer, false)
-       if err != nil {
-               return nil, err
-       }
-
-       _, err = typeSerializer.write(v.Value, buffer)
-       if err != nil {
-               return nil, err
-       }
-       return buffer.Bytes(), nil
-}
+const (
+       valueFlagNull byte = 1
+       valueFlagNone byte = 0
+)
 
 func (serializer *graphBinaryTypeSerializer) getType(val interface{}) 
(dataType, error) {
        switch val.(type) {
-       case *Bytecode, Bytecode, *GraphTraversal:
-               return bytecodeType, nil
        case string:
                return stringType, nil
        case uint, uint64, *big.Int:
@@ -678,56 +508,22 @@ func (serializer *graphBinaryTypeSerializer) getType(val 
interface{}) (dataType,
                return propertyType, nil
        case *VertexProperty:
                return vertexPropertyType, nil
-       case *Lambda:
-               return lambdaType, nil
-       case *traversalStrategy:
-               return traversalStrategyType, nil
        case *Path:
                return pathType, nil
        case Set:
                return setType, nil
        case time.Time:
-               return dateType, nil
+               return datetimeType, nil
        case time.Duration:
                return durationType, nil
-       case cardinality:
-               return cardinalityType, nil
-       case column:
-               return columnType, nil
        case direction:
                return directionType, nil
-       case operator:
-               return operatorType, nil
-       case order:
-               return orderType, nil
-       case pick:
-               return pickType, nil
-       case pop:
-               return popType, nil
        case t:
                return tType, nil
-       case barrier:
-               return barrierType, nil
-       case scope:
-               return scopeType, nil
        case merge:
                return mergeType, nil
-       case dt:
-               return dtType, nil
-       case p, Predicate:
-               return pType, nil
-       case textP, TextPredicate:
-               return textPType, nil
-       case *Binding, Binding:
-               return bindingType, nil
        case *BigDecimal, BigDecimal:
                return bigDecimalType, nil
-       case *GremlinType, GremlinType:
-               return classType, nil
-       case *Metrics, Metrics:
-               return metricsType, nil
-       case *TraversalMetrics, TraversalMetrics:
-               return traversalMetricsType, nil
        case *ByteBuffer, ByteBuffer:
                return byteBuffer, nil
        default:
@@ -926,8 +722,6 @@ func getDefaultValue(dataType dataType) interface{} {
        switch dataType {
        case intType, bigIntegerType, longType, shortType, byteType, 
booleanType, floatType, doubleType:
                return 0
-       case traverserType, stringType:
-               return ""
        case uuidType:
                return uuid.Nil
        case vertexType:
@@ -942,7 +736,7 @@ func getDefaultValue(dataType dataType) interface{} {
                return Path{}
        case setType:
                return SimpleSet{}
-       case dateType, timestampType:
+       case datetimeType:
                return time.Time{}
        case durationType:
                return time.Duration(0)
@@ -952,15 +746,28 @@ func getDefaultValue(dataType dataType) interface{} {
 }
 
 // Composite
-func readList(data *[]byte, i *int) (interface{}, error) {
+func readList(data *[]byte, i *int, flag byte) (interface{}, error) {
        sz := readIntSafe(data, i)
        var valList []interface{}
-       for j := int32(0); j < sz; j++ {
-               val, err := readFullyQualifiedNullable(data, i, true)
-               if err != nil {
-                       return nil, err
+       if flag == 0x02 {
+               for j := int32(0); j < sz; j++ {
+                       val, err := readFullyQualifiedNullable(data, i, true)
+                       if err != nil {
+                               return nil, err
+                       }
+                       bulk := readIntSafe(data, i)
+                       for k := int32(0); k < bulk; k++ {
+                               valList = append(valList, val)
+                       }
+               }
+       } else {
+               for j := int32(0); j < sz; j++ {
+                       val, err := readFullyQualifiedNullable(data, i, true)
+                       if err != nil {
+                               return nil, err
+                       }
+                       valList = append(valList, val)
                }
-               valList = append(valList, val)
        }
        return valList, nil
 }
@@ -1027,8 +834,8 @@ func readMapUnqualified(data *[]byte, i *int) 
(interface{}, error) {
        return mapData, nil
 }
 
-func readSet(data *[]byte, i *int) (interface{}, error) {
-       list, err := readList(data, i)
+func readSet(data *[]byte, i *int, flag byte) (interface{}, error) {
+       list, err := readList(data, i, flag)
        if err != nil {
                return nil, err
        }
@@ -1041,7 +848,15 @@ func readUuid(data *[]byte, i *int) (interface{}, error) {
 }
 
 func timeReader(data *[]byte, i *int) (interface{}, error) {
-       return time.UnixMilli(readLongSafe(data, i)), nil
+       year := readIntSafe(data, i)
+       month := readByteSafe(data, i)
+       day := readByteSafe(data, i)
+       ns := readLongSafe(data, i)
+       offset := readIntSafe(data, i)
+       // only way to pass offset info, timezone display is fixed to UTC as 
consequence (offset is calculated properly)
+       loc := time.FixedZone("UTC", int(offset))
+       datetime := time.Date(int(year), time.Month(month), int(day), 0, 0, 0, 
int(ns), loc)
+       return datetime, nil
 }
 
 func durationReader(data *[]byte, i *int) (interface{}, error) {
@@ -1063,11 +878,11 @@ func vertexReaderReadingProperties(data *[]byte, i *int, 
readProperties bool) (i
        if err != nil {
                return nil, err
        }
-       label, err := readUnqualified(data, i, stringType, false)
+       label, err := readUnqualified(data, i, listType, false)
        if err != nil {
                return nil, err
        }
-       v.Label = label.(string)
+       v.Label = label.([]interface{})[0].(string)
        if readProperties {
                props, err := readFullyQualifiedNullable(data, i, true)
                if err != nil {
@@ -1090,11 +905,11 @@ func edgeReader(data *[]byte, i *int) (interface{}, 
error) {
        if err != nil {
                return nil, err
        }
-       label, err := readUnqualified(data, i, stringType, false)
+       label, err := readUnqualified(data, i, listType, false)
        if err != nil {
                return nil, err
        }
-       e.Label = label.(string)
+       e.Label = label.([]interface{})[0].(string)
        v, err := vertexReaderReadingProperties(data, i, false)
        if err != nil {
                return nil, err
@@ -1142,11 +957,11 @@ func vertexPropertyReader(data *[]byte, i *int) 
(interface{}, error) {
        if err != nil {
                return nil, err
        }
-       label, err := readUnqualified(data, i, stringType, false)
+       label, err := readUnqualified(data, i, listType, false)
        if err != nil {
                return nil, err
        }
-       vp.Label = label.(string)
+       vp.Label = label.([]interface{})[0].(string)
        vp.Value, err = readFullyQualifiedNullable(data, i, true)
        if err != nil {
                return nil, err
@@ -1186,35 +1001,6 @@ func pathReader(data *[]byte, i *int) (interface{}, 
error) {
        return path, err
 }
 
-// {bulk int}{fully qualified value}
-func traverserReader(data *[]byte, i *int) (interface{}, error) {
-       var err error
-       traverser := new(Traverser)
-       traverser.bulk = readLongSafe(data, i)
-       traverser.value, err = readFullyQualifiedNullable(data, i, true)
-       if err != nil {
-               return nil, err
-       }
-       return traverser, nil
-}
-
-// {int32 length}{fully qualified item_0}{int64 repetition_0}...{fully 
qualified item_n}{int64 repetition_n}
-func bulkSetReader(data *[]byte, i *int) (interface{}, error) {
-       sz := int(readIntSafe(data, i))
-       var valList []interface{}
-       for j := 0; j < sz; j++ {
-               val, err := readFullyQualifiedNullable(data, i, true)
-               if err != nil {
-                       return nil, err
-               }
-               rep := readLongSafe(data, i)
-               for k := 0; k < int(rep); k++ {
-                       valList = append(valList, val)
-               }
-       }
-       return valList, nil
-}
-
 // {type code (always string so ignore)}{nil code (always false so 
ignore)}{int32 size}{string enum}
 func enumReader(data *[]byte, i *int) (interface{}, error) {
        typeCode := readDataType(data, i)
@@ -1225,113 +1011,14 @@ func enumReader(data *[]byte, i *int) (interface{}, 
error) {
        return readString(data, i)
 }
 
-// {unqualified key}{fully qualified value}
-func bindingReader(data *[]byte, i *int) (interface{}, error) {
-       b := new(Binding)
-       val, err := readUnqualified(data, i, stringType, false)
-       if err != nil {
-               return nil, err
-       }
-       b.Key = val.(string)
-
-       b.Value, err = readFullyQualifiedNullable(data, i, true)
-       if err != nil {
-               return nil, err
-       }
-       return b, nil
-}
-
-// {id}{name}{duration}{counts}{annotations}{nested_metrics}
-func metricsReader(data *[]byte, i *int) (interface{}, error) {
-       metrics := new(Metrics)
-       val, err := readUnqualified(data, i, stringType, false)
-       if err != nil {
-               return nil, err
-       }
-       metrics.Id = val.(string)
-
-       val, err = readUnqualified(data, i, stringType, false)
-       if err != nil {
-               return nil, err
-       }
-       metrics.Name = val.(string)
-
-       dur, err := readLong(data, i)
-       if err != nil {
-               return nil, err
-       }
-       metrics.Duration = dur.(int64)
-
-       counts, err := readMap(data, i)
-       cmap := counts.(map[interface{}]interface{})
-       if err != nil {
-               return nil, err
-       }
-       metrics.Counts = make(map[string]int64, len(cmap))
-       for k := range cmap {
-               metrics.Counts[k.(string)] = cmap[k].(int64)
-       }
-
-       annotations, err := readMap(data, i)
-       if err != nil {
-               return nil, err
-       }
-       amap := annotations.(map[interface{}]interface{})
-       if err != nil {
-               return nil, err
-       }
-       metrics.Annotations = make(map[string]interface{}, len(amap))
-       for k := range amap {
-               metrics.Annotations[k.(string)] = amap[k]
-       }
-
-       nested, err := readList(data, i)
-       if err != nil {
-               return nil, err
-       }
-       list := nested.([]interface{})
-       metrics.NestedMetrics = make([]Metrics, len(list))
-       for i, metric := range list {
-               metrics.NestedMetrics[i] = metric.(Metrics)
-       }
-
-       return metrics, nil
-}
-
-// {id}{name}{duration}{counts}{annotations}{nested_metrics}
-func traversalMetricsReader(data *[]byte, i *int) (interface{}, error) {
-       m := new(TraversalMetrics)
-       dur, err := readLong(data, i)
+func markerReader(data *[]byte, i *int) (interface{}, error) {
+       m, err := Of(readByteSafe(data, i))
        if err != nil {
                return nil, err
        }
-       m.Duration = dur.(int64)
-
-       nested, err := readList(data, i)
-       if err != nil {
-               return nil, err
-       }
-       list := nested.([]interface{})
-       m.Metrics = make([]Metrics, len(list))
-       for i, metric := range list {
-               m.Metrics[i] = *metric.(*Metrics)
-       }
-
        return m, nil
 }
 
-// Format: A String containing the fqcn.
-func readClass(data *[]byte, i *int) (interface{}, error) {
-       gremlinType := new(GremlinType)
-       str, err := readString(data, i)
-       if err != nil {
-               return nil, err
-       }
-       gremlinType.Fqcn = str.(string)
-
-       return gremlinType, nil
-}
-
 func readUnqualified(data *[]byte, i *int, dataTyp dataType, nullable bool) 
(interface{}, error) {
        if nullable && readByteSafe(data, i) == valueFlagNull {
                return getDefaultValue(dataTyp), nil
@@ -1351,9 +1038,16 @@ func readFullyQualifiedNullable(data *[]byte, i *int, 
nullable bool) (interface{
                }
                return nil, nil
        } else if nullable {
-               if readByteSafe(data, i) == valueFlagNull {
+               flag := readByteSafe(data, i)
+               if flag == valueFlagNull {
                        return getDefaultValue(dataTyp), nil
                }
+               if dataTyp == listType {
+                       return readList(data, i, flag)
+               }
+               if dataTyp == setType {
+                       return readSet(data, i, flag)
+               }
        }
        deserializer, ok := deserializers[dataTyp]
        if !ok {
diff --git a/gremlin-go/driver/graphBinary_test.go 
b/gremlin-go/driver/graphBinary_test.go
index d8c66d2816..cc80c27ccf 100644
--- a/gremlin-go/driver/graphBinary_test.go
+++ b/gremlin-go/driver/graphBinary_test.go
@@ -83,16 +83,6 @@ func TestGraphBinaryV1(t *testing.T) {
                        assert.Nil(t, err)
                        assert.Equal(t, str, res)
                })
-               t.Run("read-write GremlinType", func(t *testing.T) {
-                       pos := 0
-                       var buffer bytes.Buffer
-                       source := &GremlinType{"test fqcn"}
-                       buf, err := classWriter(source, &buffer, nil)
-                       assert.Nil(t, err)
-                       res, err := readClass(&buf, &pos)
-                       assert.Nil(t, err)
-                       assert.Equal(t, source, res)
-               })
                t.Run("read-write bool", func(t *testing.T) {
                        pos := 0
                        var buffer bytes.Buffer
@@ -198,7 +188,7 @@ func TestGraphBinaryV1(t *testing.T) {
                        source := []interface{}{int32(111), "str"}
                        buf, err := listWriter(source, &buffer, nil)
                        assert.Nil(t, err)
-                       res, err := readList(&buf, &pos)
+                       res, err := readList(&buf, &pos, 0x00)
                        assert.Nil(t, err)
                        assert.Equal(t, source, res)
                })
@@ -218,7 +208,7 @@ func TestGraphBinaryV1(t *testing.T) {
                        source := NewSimpleSet(int32(111), "str")
                        buf, err := setWriter(source, &buffer, nil)
                        assert.Nil(t, err)
-                       res, err := readSet(&buf, &pos)
+                       res, err := readSet(&buf, &pos, 0x00)
                        assert.Nil(t, err)
                        assert.Equal(t, source, res)
                })
@@ -310,7 +300,8 @@ func TestGraphBinaryV1(t *testing.T) {
                        assert.Nil(t, err)
                        res, err := timeReader(&buf, &pos)
                        assert.Nil(t, err)
-                       assert.Equal(t, source, res)
+                       // ISO format
+                       assert.Equal(t, source.Format(time.RFC3339Nano), 
res.(time.Time).Format(time.RFC3339Nano))
                })
        })
 
@@ -323,4 +314,16 @@ func TestGraphBinaryV1(t *testing.T) {
                        assert.Equal(t, 
newError(err0703ReadMapNonStringKeyError, intType), err)
                })
        })
+
+       t.Run("read-write marker", func(t *testing.T) {
+               pos := 0
+               var buffer bytes.Buffer
+               source := EndOfStream()
+               buf, err := markerWriter(source, &buffer, nil)
+               assert.Nil(t, err)
+               res, err := markerReader(&buf, &pos)
+               assert.Nil(t, err)
+               assert.Equal(t, source, res)
+       })
+
 }
diff --git a/gremlin-go/driver/marker.go b/gremlin-go/driver/marker.go
new file mode 100644
index 0000000000..bb6e855bf5
--- /dev/null
+++ b/gremlin-go/driver/marker.go
@@ -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.
+*/
+
+package gremlingo
+
+import "fmt"
+
+// Marker is used in response
+type Marker interface {
+       GetValue() byte
+}
+
+type marker struct {
+       value byte
+}
+
+func EndOfStream() Marker {
+       return marker{byte(0)}
+}
+
+func (m marker) GetValue() byte {
+       return m.value
+}
+
+func Of(value byte) (Marker, error) {
+       if value != 0 {
+               return nil, fmt.Errorf("marker value erorr")
+       }
+       return EndOfStream(), nil
+}
diff --git a/gremlin-go/driver/serializer.go b/gremlin-go/driver/serializer.go
index 04a7e468b5..c4d7da3922 100644
--- a/gremlin-go/driver/serializer.go
+++ b/gremlin-go/driver/serializer.go
@@ -228,7 +228,6 @@ func (gs graphBinarySerializer) deserializeMessage(message 
[]byte) (response, er
 
 func initSerializers() {
        serializers = map[dataType]writer{
-               bytecodeType:   bytecodeWriter,
                stringType:     stringWriter,
                bigDecimalType: bigDecimalWriter,
                bigIntegerType: bigIntWriter,
@@ -255,35 +254,21 @@ func initSerializers() {
                        err := binary.Write(buffer, binary.BigEndian, value)
                        return buffer.Bytes(), err
                },
-               vertexType:            vertexWriter,
-               edgeType:              edgeWriter,
-               propertyType:          propertyWriter,
-               vertexPropertyType:    vertexPropertyWriter,
-               lambdaType:            lambdaWriter,
-               traversalStrategyType: traversalStrategyWriter,
-               pathType:              pathWriter,
-               setType:               setWriter,
-               dateType:              timeWriter,
-               durationType:          durationWriter,
-               cardinalityType:       enumWriter,
-               columnType:            enumWriter,
-               directionType:         enumWriter,
-               dtType:                enumWriter,
-               operatorType:          enumWriter,
-               orderType:             enumWriter,
-               pickType:              enumWriter,
-               popType:               enumWriter,
-               tType:                 enumWriter,
-               barrierType:           enumWriter,
-               scopeType:             enumWriter,
-               mergeType:             enumWriter,
-               pType:                 pWriter,
-               textPType:             textPWriter,
-               bindingType:           bindingWriter,
-               mapType:               mapWriter,
-               listType:              listWriter,
-               byteBuffer:            byteBufferWriter,
-               classType:             classWriter,
+               vertexType:         vertexWriter,
+               edgeType:           edgeWriter,
+               propertyType:       propertyWriter,
+               vertexPropertyType: vertexPropertyWriter,
+               pathType:           pathWriter,
+               datetimeType:       timeWriter,
+               durationType:       durationWriter,
+               directionType:      enumWriter,
+               tType:              enumWriter,
+               mergeType:          enumWriter,
+               mapType:            mapWriter,
+               listType:           listWriter,
+               setType:            setWriter,
+               byteBuffer:         byteBufferWriter,
+               markerType:         markerWriter,
        }
 }
 
@@ -302,37 +287,29 @@ func initDeserializers() {
                stringType:     readString,
 
                // Composite
-               listType:   readList,
+               //listType:   readList,
+               //setType:    readSet,
                mapType:    readMap,
-               setType:    readSet,
                uuidType:   readUuid,
                byteBuffer: readByteBuffer,
-               classType:  readClass,
 
                // Date Time
-               dateType:      timeReader,
-               timestampType: timeReader,
-               durationType:  durationReader,
+               datetimeType: timeReader,
+               durationType: durationReader,
 
                // Graph
-               traverserType:      traverserReader,
                vertexType:         vertexReader,
                edgeType:           edgeReader,
                propertyType:       propertyReader,
                vertexPropertyType: vertexPropertyReader,
                pathType:           pathReader,
-               bulkSetType:        bulkSetReader,
                tType:              enumReader,
                directionType:      enumReader,
-               dtType:             enumReader,
-               bindingType:        bindingReader,
-
-               // Metrics
-               metricsType:          metricsReader,
-               traversalMetricsType: traversalMetricsReader,
 
                // Customer
                customType: customTypeReader,
+
+               markerType: markerReader,
        }
        customDeserializers = map[string]CustomTypeReader{}
 }

Reply via email to