Skip to content

Use encoding/json/v2 to replace current customized json implementation #3892

@flymop

Description

@flymop

Is your feature request related to a problem? Please describe.
The feature does not related to any issues or problem, it helps to reduce maintenance effort and improve performance up to 10x - especially for large set of vsphere clusters and cases that need to frequently marshal/unmarshal (e,g. monitoring)

Describe the solution you'd like
It should be fine to remove the current vim25/json package and replace the json marshal/unmarshal with new version based on encoding/json/v2.

But since the vim25/json is exported and used in external packages like vm-operator, we need to consider the backward compatibilities carefully in case break down streams.

package types

import (
	"bytes"
	"fmt"
	"io"
	"reflect"
	"time"

	"encoding/json/v2"
	"encoding/json/v2/jsontext"
)


unmarshalers := NewUnmarshalers()
unmarshalers.Add(UnmarshalFromFunc(func(dec *jsontext.Decoder, val *any) error {
    v, err := dec.ReadValue()
    if err != nil {
        return err
    }
    
    var obj map[string]RawMessage
    if err := json.Unmarshal(v, &obj); err != nil {
        return err
    }
    
    typeName, ok := obj[discriminatorMemberName]
    if !ok {
        return SkipFunc
    }
    
    // Resolve type
    var tn string
    json.Unmarshal(typeName, &tn)
    t, ok := TypeFunc()(tn)
    if !ok {
        t, ok = discriminatorTypeRegistry[tn]
    }
    if !ok {
        return fmt.Errorf("unknown type: %s", tn)
    }
    
    // Decode value
    valueData := obj[primitiveValueMemberName]
    result := reflect.New(t).Interface()
    if err := json.Unmarshal(valueData, result); err != nil {
        return err
    }
    
    *val = reflect.ValueOf(result).Elem().Interface()
    return nil
}))


func Unmarshal(input []byte, result any) error {
    err := json.Unmarshal(input, &result, json.WithUnmarshalers(unmarshalers))
    return err
}

Additional context

More description on json v2 are here:
https://go.dev/blog/jsonv2-exp
https://pkg.go.dev/github.com/go-json-experiment/json/jsontext

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions