actgardner / gogen-avro

Generate Go code to serialize and deserialize Avro schemas
MIT License
365 stars 84 forks source link

Exception when deserializing: Panic at pc 196 - (set(int)) #171

Closed tneilturner closed 2 years ago

tneilturner commented 3 years ago

Hello,

I am doing something a tad ambitious with Avro, in that I am attempting to stitch together a workable SDK in Go that will allow my team to simply pass along some JSON data and "magic happens". I am also doing some nonstandard things with maps and unions, and I suspect that it could be causing your code to be sad.

Anyway, I am able to successfully get the data to serialize properly using the LinkedIn codec, but the deserialization codec from this module panics with the cryptic error seen in the title. The value of the "pc" changes every time I try to run the codec on the same exact message, so I am a little perplexed as to what might be causing the problem.

My schema is pretty large so I don't want to just share the whole thing with you in this issue. I can, however, show you some of the bits that I believe are probably causing the issues:

  // payload is the contents of the event, including the actor, action, object graph, and
  // domain-specific payload schema
  record payload {
    entity actor;
    string action;
    object_node object_graph;
    // ADD TEAM SCHEMAS HERE
    map<union {null, org.mycompany.avro.data.Json}> data;
  }

  // entity is a generic thing in a distributed system: user, component, data/database, external or internal application, etc.
  record entity {
    // a name for the entity
    string name = "";
    // entity type enumeration
    entity_type type = "NONE";
    // the properties of the entity, can be any (or all) of the named schemas in this union
    map<union {null, org.mycompany.avro.data.Json, app, browser, device, network, library, k8s, os, robot, user, user_agent}> properties = {};
  }

This is an example of the data that gets passed for the actor field:

"actor": {
      "name": "timmy",
      "type": "CUSTOMER",
      "properties": {
        "network": {
          "org.mycompany.avro.common.network": {
            ...
          }
        },
        "robot": {
          "org.mycompany.avro.common.robot": {}
        },
        "k8s": {
          "org.mycompany.avro.common.k8s": {}
        },
        "user": {
          "org.mycompany.avro.common.user": {
           ...
          }
        },
        "app": {
          "org.mycompany.avro.common.app": {
           ...
          }
        },
        "browser": { "org.mycompany.avro.common.browser": {} },
        "device": {
          "org.mycompany.avro.common.device": {
            ...
          }
        },
        "user_agent": { "org.mycompany.avro.common.user_agent": {} },
        "os": {
          "org.mycompany.avro.common.os": {
           ...
          }
        },
        "library": {
          "org.mycompany.avro.common.library": {
           ...
          }
        }
      }
    }

As you can see, I have a union value in a map, so that it's easy to extend by simply adding new schemas to the union. Each of the org.mycompany.avro.common.* are records defined in separate *.avdl files.

I might be doing something kinda crazy, but technically the above should work, as it adheres to the Avro specification?

It's worth noting that the reason the JSON input data is nested like that is because the linkedIn codec won't let you serialize a union type unless it's in a Go native map with exactly one key, where the key is the name of the type from the union. Seems like that could be avoided, but I'm in uncharted waters here so I just structured the data that way so it would stop complaining.

Any help here would be greatly appreciated! Thanks!

tneilturner commented 3 years ago

I simplified the schema down to this:

  // entity is a generic thing in a distributed system: user, component, data/database, external or internal application, etc.
  record entity {
    // a name for the entity
    string name = "";
    // entity type enumeration
    entity_type type;
    // extensible bag of props for schemaless entities
    org.mycompany.avro.data.Json properties;
    // included entity schemas from /entities folder
    app app = {};
    browser browser = {};
    device device = {};
    network network = {};
    library library = {};
    k8s k8s = {};
    os os = {};
    robot robot = {};
    user user = {};
    user_agent user_agent = {};
  }

And I am still seeing the same error :(

actgardner commented 3 years ago

Hey @tneilturner! Sorry about this issue. Based on the simplified reproduction you posted it seems like the issue is either the entity_type enumeration, or it's in one of the nested field types (Json, app, browser, user, robot, k8s, etc.). Without knowing the schemas of those nested types it's hard for me to reproduce the issue.

If you have time, can you try bisecting the fields in the entity struct (only the first half, only the second half, then the first half of the half that failed, etc.) and narrowing down the reproduction more? That, and the code that you're using to do the serialization/deserialization round-trip would be very helpful for me to understand what's happening.

tneilturner commented 3 years ago

Thanks for the quick response!

Here is the code I use to do the serialization:

// EncodeFromJSON encodes the JSON data held in the "data" member
// It will first check the cached schemas to see if is knows of a schema for the specified
// subject and version.  If not, it will attempt to fetch a matching schema from the configured
// schema registry.  It will prefix the payload with the subject and version data at the very
// beginning of the payload as follows:
// []byte{0x0, []byte("topic here")..., 0x0, uint16 version byte 1, uint16 version byte 2, payload...}
func (av *AvroSDK) EncodeFromJSON(data []byte, subject string, version uint16) ([]byte, error) {
    if version <= 0 {
        return nil, fmt.Errorf("please specify a schema version to use that is > 0")
    }

    readerSchema, ok := av.schemaRegistryClient.Schemas()[subject][version]
    if !ok {
        err := av.schemaRegistryClient.FetchAndCache(subject, "value", version)
        if err != nil {
            return nil, err
        }
        readerSchema = av.schemaRegistryClient.Schemas()[subject][version]
    }

    if readerSchema == nil {
        return nil, fmt.Errorf("could not retrieve reader schema for encoding")
    }

    if _, ok := av.encoders[subject]; !ok {
        // create an encoder codec using the schema, this should also ensure the schema is valid
        encoder, err := linkedin.NewCodec(string(readerSchema))
        if err != nil {
            return nil, fmt.Errorf("error creating codec from schema: %v", err)
        }

        av.encoders[subject] = make(map[uint16]*linkedin.Codec)
        av.encoders[subject][version] = encoder
    }

    // step 1: read in the JSON for the schema
    var schemaMap map[string]interface{}
    err := json.Unmarshal(readerSchema, &schemaMap)
    if err != nil {
        return nil, fmt.Errorf("error unmarshaling Avro schema from JSON: %v", err)
    }

    // step 2: read in the JSON for the actual data
    var jsonMap map[string]interface{}
    err = json.Unmarshal(data, &jsonMap)
    if err != nil {
        return nil, fmt.Errorf("error unmarshalling message data from JSON: ")
    }

    // step 3: convert the map of the actual data "jsonMap" using the avro schema in "schemaMap" to an
    // internal map representation that will allow us to encode it in Avro format ("nativeMap")
    nativeMap, err := parseRecord(schemaMap, jsonMap)
    fmt.Printf("here is the internal map encoding: %v\n", nativeMap)

    if err != nil {
        return nil, err
    }

    // encode it to binary
    header := writeSubjectAndVersion(subject, version)
    binary, err := av.encoders[subject][version].BinaryFromNative(header, nativeMap)
    if err != nil {
        return nil, err
    }

    return binary, nil
}

I'm adding a custom isomorphic transformation in step 3 to handle types of org.mycompany.avro.data.Json so that the linkedin serializer can serialize any arbitrary JSON.

Here is the code to deserialize:

// DecodeToJSON decodes the data passed in the "data" parameter.  It does this by
// first reading the subject and version encoded in the binary message data to find the writer's schema,
// then uses it along with the reader's schema supplied in the "readerSchema" parameter
// in order to decode the message's payload
func (av *AvroSDK) DecodeToJSON(data []byte, readerSchema []byte) ([]byte, error) {
    subject, version, start, err := readSubjectAndVersion(data)
    if err != nil {
        return nil, err
    }

    writerSchema, ok := av.schemaRegistryClient.Schemas()[subject][version]
    if !ok {
        err = av.schemaRegistryClient.FetchAndCache(subject, "value", version)
        if err != nil {
            return nil, err
        }
        writerSchema = av.schemaRegistryClient.Schemas()[subject][version]
    }

    if writerSchema == nil {
        return nil, fmt.Errorf("could not retrieve writer schema for decoding")
    }

    // writerSchema and readerSchema may be the same schema if you're not dealing with evolution
    decoder, err := gogen.NewCodecFromSchema(writerSchema, readerSchema)
    if err != nil {
        return nil, err
    }

    // decode the data
    result, err := decoder.Deserialize(bytes.NewBuffer(data[start:]))
    if err != nil {
        return nil, err
    }

    resultJSON, err := json.Marshal(result)
    if err != nil {
        return nil, err
    }

    return resultJSON, nil
}

I will try narrowing down the issue by systematically removing fields from the entity struct, and report back what I see happening.

tneilturner commented 3 years ago

I have narrowed down the failure to be definitely caused by the enum types. The k8s.avdl file also has an enum in it that was causing the same kind of failure. If I remove both the entity_type and k8s fields, it works.

For reference, this is the k8s schema:

@namespace("org.mycompany.avro.common")
protocol K8S {
    enum kind {
        NONE,
        POD,
        INGRESS,
        SERVICE,
        DEPLOYMENT,
        REPLICASET,
        STATEFULSET
    } = NONE;

    record k8s {
        map<string> labels = {};
        kind kind = "NONE";
    }
}
actgardner commented 3 years ago

@tneilturner Thanks for narrowing down the issue. This looks like a bug in the generic deserialization part of the library, I've released v9.1.0 which should support deserializing enums.

Note that there is an issue #167 which documents some limitations around enums. If you're using the same schema to read and write them, you shouldn't have any problems, but evolution currently doesn't resolve symbols correctly. This should be fixed in the next major release.

tneilturner commented 3 years ago

Great! Thank you so much!

tneilturner commented 3 years ago

Hi again... I just bumped up the version, and tried again but with no luck. :(

The error message is different now:

Panic at pc 187 -  (exit())
actgardner commented 3 years ago

Hey @tneilturner, that looks like a separate issue - can you enable logging and post the logs? https://github.com/actgardner/gogen-avro#reporting-issues

tneilturner commented 3 years ago

Absolutely, my apologies for not doing that to begin with.

Here they are:

{"level":"info","app":"schema-registry-poc-consumer","env":"dev","git.sha":"","context":{},"created":"2021-09-12T13:42:41Z","message":"successfully fetched reader schema for topic: poc-22, version: 1"}
{"level":"info","app":"schema-registry-poc-consumer","env":"dev","git.sha":"","context":{},"created":"2021-09-12T13:42:41Z","message":"ParallelFIFOStream Consumer starting..."}
{"level":"info","app":"schema-registry-poc-consumer","env":"dev","git.sha":"","context":{},"created":"2021-09-12T13:42:41Z","message":"consumer up and running!"}
{"level":"info","app":"schema-registry-poc-consumer","env":"dev","git.sha":"","context":{},"created":"2021-09-12T13:42:41Z","message":"claim processing starting on Topic: poc-22, Partition: 0"}
{"level":"info","app":"schema-registry-poc-consumer","env":"dev","git.sha":"","context":{},"created":"2021-09-12T13:42:41Z","message":"initial offset initialized to sarama.OffsetNewest, using starting offset of first message..."}
{"level":"info","app":"schema-registry-poc-consumer","env":"dev","git.sha":"","context":{},"created":"2021-09-12T13:42:48Z","message":"starting processing at offset 7"}
Compile()
 writer:
 &{org.mycompany.avro.common.common_event_schema 0xc00040dab0}
---
reader: &{org.mycompany.avro.common.common_event_schema 0xc00040d260}
---

compileType()
 writer:
 &{org.mycompany.avro.common.common_event_schema 0xc00040dab0}
---
reader: &{org.mycompany.avro.common.common_event_schema 0xc00040d260}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.common_event_schema 0xc00040dab0}
---
reader: &{org.mycompany.avro.common.common_event_schema 0xc00040d260}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common common_event_schema} [] [0xc000440d80 0xc00044cc80 0xc00044cd00]  map[fields:[map[name:header type:map[fields:[map[name:domain type:string] map[name:timestamp type:string] map[name:correlation_id type:string] map[name:event_id type:string] map[name:labels type:map[type:map values:string]]] name:header type:record]] map[name:payload type:map[fields:[map[name:actor type:map[fields:[map[default: name:name type:string] map[name:type type:map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]] map[name:properties type:map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]] map[default:map[] name:app type:map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]] map[default:map[] name:browser type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]] map[default:map[] name:device type:map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]] map[default:map[] name:k8s type:map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]] map[default:map[] name:library type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]] map[default:map[] name:network type:map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]] map[default:map[] name:os type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]] map[default:map[] name:robot type:map[fields:[map[default: name:name type:string]] name:robot type:record]] map[default:map[] name:user type:map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]] map[default:map[] name:user_agent type:map[fields:[map[default: name:data type:string]] name:user_agent type:record]]] name:entity type:record]] map[name:action type:string] map[name:object_graph type:map[fields:[map[name:object type:entity] map[default:map[] name:relations type:map[type:map values:map[items:object_node type:array]]]] name:object_node type:record]] map[name:data type:org.mycompany.avro.data.Json]] name:payload type:record]] map[name:extended_context type:org.mycompany.avro.data.Json]] name:common_event_schema namespace:org.mycompany.avro.common type:record]}
---
reader: &{{org.mycompany.avro.common common_event_schema} [] [0xc00041a700 0xc000440600 0xc000440680]  map[fields:[map[name:header type:map[fields:[map[name:domain type:string] map[name:timestamp type:string] map[name:correlation_id type:string] map[name:event_id type:string] map[name:labels type:map[type:map values:string]]] name:header type:record]] map[name:payload type:map[fields:[map[name:actor type:map[fields:[map[default: name:name type:string] map[name:type type:map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]] map[name:properties type:map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]] map[default:map[] name:app type:map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]] map[default:map[] name:browser type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]] map[default:map[] name:device type:map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]] map[default:map[] name:k8s type:map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]] map[default:map[] name:library type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]] map[default:map[] name:network type:map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]] map[default:map[] name:os type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]] map[default:map[] name:robot type:map[fields:[map[default: name:name type:string]] name:robot type:record]] map[default:map[] name:user type:map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]] map[default:map[] name:user_agent type:map[fields:[map[default: name:data type:string]] name:user_agent type:record]]] name:entity type:record]] map[name:action type:string] map[name:object_graph type:map[fields:[map[name:object type:entity] map[default:map[] name:relations type:map[type:map values:map[items:object_node type:array]]]] name:object_node type:record]] map[name:data type:org.mycompany.avro.data.Json]] name:payload type:record]] map[name:extended_context type:org.mycompany.avro.data.Json]] name:common_event_schema namespace:org.mycompany.avro.common type:record]}
---

compileType()
 writer:
 &{org.mycompany.avro.common.header 0xc00040d2d0}
---
reader: &{org.mycompany.avro.common.header 0xc00040ca80}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.header 0xc00040d2d0}
---
reader: &{org.mycompany.avro.common.header 0xc00040ca80}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common header} [] [0xc000440b00 0xc000440b80 0xc000440c00 0xc000440c80 0xc000440d00]  map[fields:[map[name:domain type:string] map[name:timestamp type:string] map[name:correlation_id type:string] map[name:event_id type:string] map[name:labels type:map[type:map values:string]]] name:header type:record]}
---
reader: &{{org.mycompany.avro.common header} [] [0xc00041a480 0xc00041a500 0xc00041a580 0xc00041a600 0xc00041a680]  map[fields:[map[name:domain type:string] map[name:timestamp type:string] map[name:correlation_id type:string] map[name:event_id type:string] map[name:labels type:map[type:map values:string]]] name:header type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{0xc000413360 map[type:map values:string]}
---
reader: &{0xc000412410 map[type:map values:string]}
---

compileMap()
 writer:
 &{0xc000413360 map[type:map values:string]}
---
reader: &{0xc000412410 map[type:map values:string]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.payload 0xc00040da40}
---
reader: &{org.mycompany.avro.common.payload 0xc00040d1f0}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.payload 0xc00040da40}
---
reader: &{org.mycompany.avro.common.payload 0xc00040d1f0}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common payload} [] [0xc00044c980 0xc00044ca00 0xc00044cb80 0xc00044cc00]  map[fields:[map[name:actor type:map[fields:[map[default: name:name type:string] map[name:type type:map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]] map[name:properties type:map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]] map[default:map[] name:app type:map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]] map[default:map[] name:browser type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]] map[default:map[] name:device type:map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]] map[default:map[] name:k8s type:map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]] map[default:map[] name:library type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]] map[default:map[] name:network type:map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]] map[default:map[] name:os type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]] map[default:map[] name:robot type:map[fields:[map[default: name:name type:string]] name:robot type:record]] map[default:map[] name:user type:map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]] map[default:map[] name:user_agent type:map[fields:[map[default: name:data type:string]] name:user_agent type:record]]] name:entity type:record]] map[name:action type:string] map[name:object_graph type:map[fields:[map[name:object type:entity] map[default:map[] name:relations type:map[type:map values:map[items:object_node type:array]]]] name:object_node type:record]] map[name:data type:org.mycompany.avro.data.Json]] name:payload type:record]}
---
reader: &{{org.mycompany.avro.common payload} [] [0xc000440300 0xc000440380 0xc000440500 0xc000440580]  map[fields:[map[name:actor type:map[fields:[map[default: name:name type:string] map[name:type type:map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]] map[name:properties type:map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]] map[default:map[] name:app type:map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]] map[default:map[] name:browser type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]] map[default:map[] name:device type:map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]] map[default:map[] name:k8s type:map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]] map[default:map[] name:library type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]] map[default:map[] name:network type:map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]] map[default:map[] name:os type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]] map[default:map[] name:robot type:map[fields:[map[default: name:name type:string]] name:robot type:record]] map[default:map[] name:user type:map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]] map[default:map[] name:user_agent type:map[fields:[map[default: name:data type:string]] name:user_agent type:record]]] name:entity type:record]] map[name:action type:string] map[name:object_graph type:map[fields:[map[name:object type:entity] map[default:map[] name:relations type:map[type:map values:map[items:object_node type:array]]]] name:object_node type:record]] map[name:data type:org.mycompany.avro.data.Json]] name:payload type:record]}
---

compileType()
 writer:
 &{org.mycompany.avro.common.entity 0xc00040d960}
---
reader: &{org.mycompany.avro.common.entity 0xc00040d110}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.entity 0xc00040d960}
---
reader: &{org.mycompany.avro.common.entity 0xc00040d110}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common entity} [] [0xc000440e00 0xc000440e80 0xc000441000 0xc000441380 0xc000441580 0xc000441900 0xc000441a80 0xc000441c00 0xc000441e80 0xc00044c080 0xc00044c180 0xc00044c800 0xc00044c900]  map[fields:[map[default: name:name type:string] map[name:type type:map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]] map[name:properties type:map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]] map[default:map[] name:app type:map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]] map[default:map[] name:browser type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]] map[default:map[] name:device type:map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]] map[default:map[] name:k8s type:map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]] map[default:map[] name:library type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]] map[default:map[] name:network type:map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]] map[default:map[] name:os type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]] map[default:map[] name:robot type:map[fields:[map[default: name:name type:string]] name:robot type:record]] map[default:map[] name:user type:map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]] map[default:map[] name:user_agent type:map[fields:[map[default: name:data type:string]] name:user_agent type:record]]] name:entity type:record]}
---
reader: &{{org.mycompany.avro.common entity} [] [0xc00041a780 0xc00041a800 0xc00041a980 0xc00041ad00 0xc00041af00 0xc00041b280 0xc00041b400 0xc00041b580 0xc00041b800 0xc00041ba00 0xc00041bb00 0xc000440180 0xc000440280]  map[fields:[map[default: name:name type:string] map[name:type type:map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]] map[name:properties type:map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]] map[default:map[] name:app type:map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]] map[default:map[] name:browser type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]] map[default:map[] name:device type:map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]] map[default:map[] name:k8s type:map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]] map[default:map[] name:library type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]] map[default:map[] name:network type:map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]] map[default:map[] name:os type:map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]] map[default:map[] name:robot type:map[fields:[map[default: name:name type:string]] name:robot type:record]] map[default:map[] name:user type:map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]] map[default:map[] name:user_agent type:map[fields:[map[default: name:data type:string]] name:user_agent type:record]]] name:entity type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.entity_type 0xc00040d340}
---
reader: &{org.mycompany.avro.common.entity_type 0xc00040caf0}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.entity_type 0xc00040d340}
---
reader: &{org.mycompany.avro.common.entity_type 0xc00040caf0}
---

compileEnum()
 writer:
 &{{org.mycompany.avro.common entity_type} [] [NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY]  map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]}
---
reader: &{{org.mycompany.avro.common entity_type} [] [NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY]  map[default:NONE name:entity_type symbols:[NONE ASK BID CUSTOMER PRODUCT ADVERTISEMENT BANNER MEDIA_IMAGE WEB_PAGE DATABASE SCHEMA MICROSERVICE K8S_CLUSTER K8S_SERVICE K8S_POD K8S_DEPLOYMENT CONTAINER INGRESS GATEWAY LOADBALANCER KAFKA_BROKER KAFKA_STREAM KAFKA_CONSUMER KAFKA_PRODUCER S3_BUCKET AWS_LAMBDA AWS_KINESIS APACHE_FLINK EC2_INSTANCE SCHEMA_REGISTRY] type:enum]}
---

compileType()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileRef()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.data Json} [] [0xc000440f80]  map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]}
---
reader: &{{org.mycompany.avro.data Json} [] [0xc00041a900]  map[fields:[map[default:<nil> name:value type:[null double string boolean long map[items:Json type:array] map[type:map values:Json]]]] name:Json namespace:org.mycompany.avro.data type:record]}
---

compileType()
 writer:
 &{ [0xc000413400 0xc000413450 0xc0004134a0 0xc0004134f0 0xc000413540 0xc00042a480 0xc00042a498] [null double string boolean long map[items:Json type:array] map[type:map values:Json]] 0}
---
reader: &{ [0xc0004124b0 0xc000412500 0xc000412550 0xc0004125a0 0xc0004125f0 0xc00042a1f8 0xc00042a210] [null double string boolean long map[items:Json type:array] map[type:map values:Json]] 0}
---

compileUnion()
 writer:
 &{ [0xc000413400 0xc000413450 0xc0004134a0 0xc0004134f0 0xc000413540 0xc00042a480 0xc00042a498] [null double string boolean long map[items:Json type:array] map[type:map values:Json]] 0}
---
reader: &{ [0xc0004124b0 0xc000412500 0xc000412550 0xc0004125a0 0xc0004125f0 0xc00042a1f8 0xc00042a210] [null double string boolean long map[items:Json type:array] map[type:map values:Json]] 0}
---

Union types have exact match by name: "Null" "Null"
Union types have exact match by name: "Double" "Double"
compileType()
 writer:
 &{{double Double float64 vm.WriteDouble double}}
---
reader: &{{double Double float64 vm.WriteDouble double}}
---

Union types have exact match by name: "String" "String"
compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

Union types have exact match by name: "Bool" "Bool"
compileType()
 writer:
 &{{boolean Bool bool vm.WriteBool boolean}}
---
reader: &{{boolean Bool bool vm.WriteBool boolean}}
---

Union types have exact match by name: "Long" "Long"
compileType()
 writer:
 &{{long Long int64 vm.WriteLong long}}
---
reader: &{{long Long int64 vm.WriteLong long}}
---

Union types have exact match by name: "ArrayJson" "ArrayJson"
compileType()
 writer:
 &{0xc00043d800 map[items:Json type:array]}
---
reader: &{0xc000409f80 map[items:Json type:array]}
---

compileArray()
 writer:
 &{0xc00043d800 map[items:Json type:array]}
---
reader: &{0xc000409f80 map[items:Json type:array]}
---

compileType()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileRef()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

Union types have exact match by name: "MapJson" "MapJson"
compileType()
 writer:
 &{0xc00043d830 map[type:map values:Json]}
---
reader: &{0xc000409fb0 map[type:map values:Json]}
---

compileMap()
 writer:
 &{0xc00043d830 map[type:map values:Json]}
---
reader: &{0xc000409fb0 map[type:map values:Json]}
---

compileType()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileRef()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileType()
 writer:
 &{org.mycompany.avro.common.app 0xc00040d420}
---
reader: &{org.mycompany.avro.common.app 0xc00040cbd0}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.app 0xc00040d420}
---
reader: &{org.mycompany.avro.common.app 0xc00040cbd0}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common app} [] [0xc000441080 0xc000441100 0xc000441180 0xc000441200 0xc000441280 0xc000441300]  map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]}
---
reader: &{{org.mycompany.avro.common app} [] [0xc00041aa00 0xc00041aa80 0xc00041ab00 0xc00041ab80 0xc00041ac00 0xc00041ac80]  map[fields:[map[default: name:build type:string] map[default: name:git_sha type:string] map[default: name:name type:string] map[default: name:namespace type:string] map[default: name:version type:string] map[default:map[] name:extensions type:org.mycompany.avro.data.Json]] name:app type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileRef()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileType()
 writer:
 &{org.mycompany.avro.common.browser 0xc00040d490}
---
reader: &{org.mycompany.avro.common.browser 0xc00040cc40}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.browser 0xc00040d490}
---
reader: &{org.mycompany.avro.common.browser 0xc00040cc40}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common browser} [] [0xc000441400 0xc000441480]  map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]}
---
reader: &{{org.mycompany.avro.common browser} [] [0xc00041ad80 0xc00041ae00]  map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:browser type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.device 0xc00040d500}
---
reader: &{org.mycompany.avro.common.device 0xc00040ccb0}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.device 0xc00040d500}
---
reader: &{org.mycompany.avro.common.device 0xc00040ccb0}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common device} [] [0xc000441600 0xc000441680 0xc000441700 0xc000441780 0xc000441800 0xc000441880]  map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]}
---
reader: &{{org.mycompany.avro.common device} [] [0xc00041af80 0xc00041b000 0xc00041b080 0xc00041b100 0xc00041b180 0xc00041b200]  map[fields:[map[default:false name:adTrackingEnabled type:boolean] map[default: name:id type:string] map[default: name:manufacturer type:string] map[default: name:model type:string] map[default: name:name type:string] map[default: name:type type:string]] name:device type:record]}
---

compileType()
 writer:
 &{{boolean Bool bool vm.WriteBool boolean}}
---
reader: &{{boolean Bool bool vm.WriteBool boolean}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.k8s 0xc00040d650}
---
reader: &{org.mycompany.avro.common.k8s 0xc00040ce00}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.k8s 0xc00040d650}
---
reader: &{org.mycompany.avro.common.k8s 0xc00040ce00}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common k8s} [] [0xc000441980 0xc000441a00]  map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]}
---
reader: &{{org.mycompany.avro.common k8s} [] [0xc00041b300 0xc00041b380]  map[fields:[map[default:map[] name:labels type:map[type:map values:string]] map[default:NONE name:kind type:map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]]] name:k8s type:record]}
---

compileType()
 writer:
 &{0xc0004139f0 map[type:map values:string]}
---
reader: &{0xc000412aa0 map[type:map values:string]}
---

compileMap()
 writer:
 &{0xc0004139f0 map[type:map values:string]}
---
reader: &{0xc000412aa0 map[type:map values:string]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.kind 0xc00040d5e0}
---
reader: &{org.mycompany.avro.common.kind 0xc00040cd90}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.kind 0xc00040d5e0}
---
reader: &{org.mycompany.avro.common.kind 0xc00040cd90}
---

compileEnum()
 writer:
 &{{org.mycompany.avro.common kind} [] [NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET]  map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]}
---
reader: &{{org.mycompany.avro.common kind} [] [NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET]  map[default:NONE name:kind symbols:[NONE POD INGRESS SERVICE DEPLOYMENT REPLICASET STATEFULSET] type:enum]}
---

compileType()
 writer:
 &{org.mycompany.avro.common.library 0xc00040d6c0}
---
reader: &{org.mycompany.avro.common.library 0xc00040ce70}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.library 0xc00040d6c0}
---
reader: &{org.mycompany.avro.common.library 0xc00040ce70}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common library} [] [0xc000441b00 0xc000441b80]  map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]}
---
reader: &{{org.mycompany.avro.common library} [] [0xc00041b480 0xc00041b500]  map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:library type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.network 0xc00040d730}
---
reader: &{org.mycompany.avro.common.network 0xc00040cee0}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.network 0xc00040d730}
---
reader: &{org.mycompany.avro.common.network 0xc00040cee0}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common network} [] [0xc000441c80 0xc000441d00 0xc000441d80 0xc000441e00]  map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]}
---
reader: &{{org.mycompany.avro.common network} [] [0xc00041b600 0xc00041b680 0xc00041b700 0xc00041b780]  map[fields:[map[default: name:carrier type:string] map[default:false name:is_cellular type:boolean] map[default: name:ip type:string] map[default:false name:is_wifi type:boolean]] name:network type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{boolean Bool bool vm.WriteBool boolean}}
---
reader: &{{boolean Bool bool vm.WriteBool boolean}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{boolean Bool bool vm.WriteBool boolean}}
---
reader: &{{boolean Bool bool vm.WriteBool boolean}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.os 0xc00040d7a0}
---
reader: &{org.mycompany.avro.common.os 0xc00040cf50}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.os 0xc00040d7a0}
---
reader: &{org.mycompany.avro.common.os 0xc00040cf50}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common os} [] [0xc000441f80 0xc00044c000]  map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]}
---
reader: &{{org.mycompany.avro.common os} [] [0xc00041b900 0xc00041b980]  map[fields:[map[default: name:name type:string] map[default: name:version type:string]] name:os type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.robot 0xc00040d810}
---
reader: &{org.mycompany.avro.common.robot 0xc00040cfc0}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.robot 0xc00040d810}
---
reader: &{org.mycompany.avro.common.robot 0xc00040cfc0}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common robot} [] [0xc00044c100]  map[fields:[map[default: name:name type:string]] name:robot type:record]}
---
reader: &{{org.mycompany.avro.common robot} [] [0xc00041ba80]  map[fields:[map[default: name:name type:string]] name:robot type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.user 0xc00040d880}
---
reader: &{org.mycompany.avro.common.user 0xc00040d030}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.user 0xc00040d880}
---
reader: &{org.mycompany.avro.common.user 0xc00040d030}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common user} [] [0xc00044c200 0xc00044c280 0xc00044c300 0xc00044c380 0xc00044c400 0xc00044c480 0xc00044c500 0xc00044c580 0xc00044c600 0xc00044c700 0xc00044c780]  map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]}
---
reader: &{{org.mycompany.avro.common user} [] [0xc00041bb80 0xc00041bc00 0xc00041bc80 0xc00041bd00 0xc00041bd80 0xc00041be00 0xc00041be80 0xc00041bf00 0xc00041bf80 0xc000440080 0xc000440100]  map[fields:[map[default: name:anonymousId type:string] map[default: name:createdAt type:string] map[default: name:currencyPreference type:string] map[default: name:anonymousEmail type:string] map[default: name:anonymousFirstName type:string] map[default: name:anonymousLastName type:string] map[default: name:local_timezone type:string] map[default: name:locale type:string] map[default: name:userId type:string] map[default: name:userName type:string] map[default:[] name:vices type:map[items:string type:array]]] name:user type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{0xc00044e050 map[items:string type:array]}
---
reader: &{0xc0004130e0 map[items:string type:array]}
---

compileArray()
 writer:
 &{0xc00044e050 map[items:string type:array]}
---
reader: &{0xc0004130e0 map[items:string type:array]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.user_agent 0xc00040d8f0}
---
reader: &{org.mycompany.avro.common.user_agent 0xc00040d0a0}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.user_agent 0xc00040d8f0}
---
reader: &{org.mycompany.avro.common.user_agent 0xc00040d0a0}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common user_agent} [] [0xc00044c880]  map[fields:[map[default: name:data type:string]] name:user_agent type:record]}
---
reader: &{{org.mycompany.avro.common user_agent} [] [0xc000440200]  map[fields:[map[default: name:data type:string]] name:user_agent type:record]}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{{string String string vm.WriteString string}}
---
reader: &{{string String string vm.WriteString string}}
---

compileType()
 writer:
 &{org.mycompany.avro.common.object_node 0xc00040d9d0}
---
reader: &{org.mycompany.avro.common.object_node 0xc00040d180}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.object_node 0xc00040d9d0}
---
reader: &{org.mycompany.avro.common.object_node 0xc00040d180}
---

compileRecord()
 writer:
 &{{org.mycompany.avro.common object_node} [] [0xc00044ca80 0xc00044cb00]  map[fields:[map[name:object type:entity] map[default:map[] name:relations type:map[type:map values:map[items:object_node type:array]]]] name:object_node type:record]}
---
reader: &{{org.mycompany.avro.common object_node} [] [0xc000440400 0xc000440480]  map[fields:[map[name:object type:entity] map[default:map[] name:relations type:map[type:map values:map[items:object_node type:array]]]] name:object_node type:record]}
---

compileType()
 writer:
 &{org.mycompany.avro.common.entity 0xc00040d960}
---
reader: &{org.mycompany.avro.common.entity 0xc00040d110}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.entity 0xc00040d960}
---
reader: &{org.mycompany.avro.common.entity 0xc00040d110}
---

compileType()
 writer:
 &{0xc00042a4e0 map[type:map values:map[items:object_node type:array]]}
---
reader: &{0xc00042a258 map[type:map values:map[items:object_node type:array]]}
---

compileMap()
 writer:
 &{0xc00042a4e0 map[type:map values:map[items:object_node type:array]]}
---
reader: &{0xc00042a258 map[type:map values:map[items:object_node type:array]]}
---

compileType()
 writer:
 &{0xc00043db30 map[items:object_node type:array]}
---
reader: &{0xc00043c2d0 map[items:object_node type:array]}
---

compileArray()
 writer:
 &{0xc00043db30 map[items:object_node type:array]}
---
reader: &{0xc00043c2d0 map[items:object_node type:array]}
---

compileType()
 writer:
 &{org.mycompany.avro.common.object_node 0xc00040d9d0}
---
reader: &{org.mycompany.avro.common.object_node 0xc00040d180}
---

compileRef()
 writer:
 &{org.mycompany.avro.common.object_node 0xc00040d9d0}
---
reader: &{org.mycompany.avro.common.object_node 0xc00040d180}
---

compileType()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileRef()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileType()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

compileRef()
 writer:
 &{org.mycompany.avro.data.Json 0xc00040d3b0}
---
reader: &{org.mycompany.avro.data.Json 0xc00040cb60}
---

&{0xc000403480 map[record-rw-App:0xc000403700 record-rw-Browser:0xc000403780 record-rw-Common_event_schema:0xc0004034c0 record-rw-Device:0xc000403800 record-rw-Entity:0xc000403600 record-rw-Header:0xc000403500 record-rw-Json:0xc000403680 record-rw-K8s:0xc000403880 record-rw-Library:0xc000403900 record-rw-Network:0xc000403980 record-rw-Object_node:0xc000403c80 record-rw-Os:0xc000403a00 record-rw-Payload:0xc0004035c0 record-rw-Robot:0xc000403a80 record-rw-User:0xc000403b00 record-rw-User_agent:0xc000403bc0] [0xc000401c30 0xc0004ce070 0xc0004ce170 0xc0004ce6e0 0xc0004cee10 0xc0004cf000 0xc0004cf040] [0xc00042a660] [Unsupported type for union] false}
findOffsets() block 5 - start 122
findOffsets() block 6 - start 132
findOffsets() block 6 - end 143
findOffsets() block 5 - end 149
findOffsets() block 0 - start 158
findOffsets() block 0 - start 173
findOffsets() block 0 - start 175
findOffsets() block 0 - start 176
findOffsets() block 0 - start 183
findOffsets() block 0 - start 184
findOffsets() block 0 - start 191
findOffsets() block 0 - start 192
findOffsets() block 0 - start 199
findOffsets() block 0 - start 200
findOffsets() block 0 - start 207
findOffsets() block 0 - start 208
findOffsets() block 1 - start 212
findOffsets() block 1 - end 223
findOffsets() block 0 - start 229
findOffsets() block 0 - start 230
findOffsets() block 2 - start 234
findOffsets() block 2 - end 246
findOffsets() block 0 - end 252
findOffsets() block 0 - start 271
findOffsets() block 0 - end 284
findOffsets() block 3 - start 316
findOffsets() block 3 - end 329
findOffsets() block 4 - start 386
findOffsets() block 4 - end 398
Found blocks: [271 - 284 212 - 223 234 - 246 316 - 329 386 - 398 122 - 149 132 - 143]
0:  call(305)
1:  halt(0)
2:  enter(0)
3:  |  read(string)
4:  |  set(string)
5:  exit()
6:  enter(1)
7:  |  read(string)
8:  |  set(string)
9:  exit()
10: return()
11: enter(0)
12: |  read(string)
13: |  set(string)
14: exit()
15: enter(1)
16: |  read(int)
17: |  set(int)
18: exit()
19: enter(2)
20: |  call(156)
21: exit()
22: enter(3)
23: |  call(405)
24: exit()
25: enter(4)
26: |  call(2)
27: exit()
28: enter(5)
29: |  call(53)
30: exit()
31: enter(6)
32: |  call(315)
33: exit()
34: enter(7)
35: |  call(78)
36: exit()
37: enter(8)
38: |  call(87)
39: exit()
40: enter(9)
41: |  call(104)
42: exit()
43: enter(10)
44: |  call(340)
45: exit()
46: enter(11)
47: |  call(345)
48: exit()
49: enter(12)
50: |  call(113)
51: exit()
52: return()
53: enter(0)
54: |  read(boolean)
55: |  set(boolean)
56: exit()
57: enter(1)
58: |  read(string)
59: |  set(string)
60: exit()
61: enter(2)
62: |  read(string)
63: |  set(string)
64: exit()
65: enter(3)
66: |  read(string)
67: |  set(string)
68: exit()
69: enter(4)
70: |  read(string)
71: |  set(string)
72: exit()
73: enter(5)
74: |  read(string)
75: |  set(string)
76: exit()
77: return()
78: enter(0)
79: |  read(string)
80: |  set(string)
81: exit()
82: enter(1)
83: |  read(string)
84: |  set(string)
85: exit()
86: return()
87: enter(0)
88: |  read(string)
89: |  set(string)
90: exit()
91: enter(1)
92: |  read(boolean)
93: |  set(boolean)
94: exit()
95: enter(2)
96: |  read(string)
97: |  set(string)
98: exit()
99: enter(3)
100:    |  read(boolean)
101:    |  set(boolean)
102:    exit()
103:    return()
104:    enter(0)
105:    |  read(string)
106:    |  set(string)
107:    exit()
108:    enter(1)
109:    |  read(string)
110:    |  set(string)
111:    exit()
112:    return()
113:    enter(0)
114:    |  read(string)
115:    |  set(string)
116:    exit()
117:    return()
118:    enter(0)
119:    |  call(11)
120:    exit()
121:    enter(1)
122:    |  read(long)
123:    |  eval_equal(0)
124:    |  cond_jump(154)
125:    |  eval_greater(0)
126:    |  cond_jump(129)
127:    |  read(UnusedLong)
128:    |  mult_long(-1)
129:    |  push_loop(0)
130:    |  read(string)
131:    |  append_map(0)
132:    |  |  read(long)
133:    |  |  eval_equal(0)
134:    |  |  cond_jump(148)
135:    |  |  eval_greater(0)
136:    |  |  cond_jump(139)
137:    |  |  read(UnusedLong)
138:    |  |  mult_long(-1)
139:    |  |  push_loop(0)
140:    |  |  append_array(0)
141:    |  |  |  call(118)
142:    |  |  exit(0)
143:    |  |  pop_loop(0)
144:    |  |  add_long(-1)
145:    |  |  eval_equal(0)
146:    |  |  cond_jump(132)
147:    |  |  jump(139)
148:    |  exit(0)
149:    |  pop_loop(0)
150:    |  add_long(-1)
151:    |  eval_equal(0)
152:    |  cond_jump(122)
153:    |  jump(129)
154:    exit()
155:    return()
156:    enter(0)
157:    |  read(long)
158:    |  eval_equal(0)
159:    |  cond_jump(174)
160:    |  eval_equal(1)
161:    |  cond_jump(177)
162:    |  eval_equal(2)
163:    |  cond_jump(185)
164:    |  eval_equal(3)
165:    |  cond_jump(193)
166:    |  eval_equal(4)
167:    |  cond_jump(201)
168:    |  eval_equal(5)
169:    |  cond_jump(209)
170:    |  eval_equal(6)
171:    |  cond_jump(231)
172:    |  halt(1)
173:    |  jump(252)
174:    |  set_exit_null()
175:    |  jump(252)
176:    |  jump(252)
177:    |  set_long(1)
178:    |  set(long)
179:    |  enter(1)
180:    |  |  read(double)
181:    |  |  set(double)
182:    |  exit()
183:    |  jump(252)
184:    |  jump(252)
185:    |  set_long(2)
186:    |  set(long)
187:    |  enter(2)
188:    |  |  read(string)
189:    |  |  set(string)
190:    |  exit()
191:    |  jump(252)
192:    |  jump(252)
193:    |  set_long(3)
194:    |  set(long)
195:    |  enter(3)
196:    |  |  read(boolean)
197:    |  |  set(boolean)
198:    |  exit()
199:    |  jump(252)
200:    |  jump(252)
201:    |  set_long(4)
202:    |  set(long)
203:    |  enter(4)
204:    |  |  read(long)
205:    |  |  set(long)
206:    |  exit()
207:    |  jump(252)
208:    |  jump(252)
209:    |  set_long(5)
210:    |  set(long)
211:    |  enter(5)
212:    |  |  read(long)
213:    |  |  eval_equal(0)
214:    |  |  cond_jump(228)
215:    |  |  eval_greater(0)
216:    |  |  cond_jump(219)
217:    |  |  read(UnusedLong)
218:    |  |  mult_long(-1)
219:    |  |  push_loop(0)
220:    |  |  append_array(0)
221:    |  |  |  call(156)
222:    |  |  exit(0)
223:    |  |  pop_loop(0)
224:    |  |  add_long(-1)
225:    |  |  eval_equal(0)
226:    |  |  cond_jump(212)
227:    |  |  jump(219)
228:    |  exit()
229:    |  jump(252)
230:    |  jump(252)
231:    |  set_long(6)
232:    |  set(long)
233:    |  enter(6)
234:    |  |  read(long)
235:    |  |  eval_equal(0)
236:    |  |  cond_jump(251)
237:    |  |  eval_greater(0)
238:    |  |  cond_jump(241)
239:    |  |  read(UnusedLong)
240:    |  |  mult_long(-1)
241:    |  |  push_loop(0)
242:    |  |  read(string)
243:    |  |  append_map(0)
244:    |  |  |  call(156)
245:    |  |  exit(0)
246:    |  |  pop_loop(0)
247:    |  |  add_long(-1)
248:    |  |  eval_equal(0)
249:    |  |  cond_jump(234)
250:    |  |  jump(241)
251:    |  exit()
252:    exit()
253:    return()
254:    enter(0)
255:    |  read(string)
256:    |  set(string)
257:    exit()
258:    enter(1)
259:    |  read(string)
260:    |  set(string)
261:    exit()
262:    enter(2)
263:    |  read(string)
264:    |  set(string)
265:    exit()
266:    enter(3)
267:    |  read(string)
268:    |  set(string)
269:    exit()
270:    enter(4)
271:    |  read(long)
272:    |  eval_equal(0)
273:    |  cond_jump(289)
274:    |  eval_greater(0)
275:    |  cond_jump(278)
276:    |  read(UnusedLong)
277:    |  mult_long(-1)
278:    |  push_loop(0)
279:    |  read(string)
280:    |  append_map(0)
281:    |  |  read(string)
282:    |  |  set(string)
283:    |  exit(0)
284:    |  pop_loop(0)
285:    |  add_long(-1)
286:    |  eval_equal(0)
287:    |  cond_jump(271)
288:    |  jump(278)
289:    exit()
290:    return()
291:    enter(0)
292:    |  call(11)
293:    exit()
294:    enter(1)
295:    |  read(string)
296:    |  set(string)
297:    exit()
298:    enter(2)
299:    |  call(118)
300:    exit()
301:    enter(3)
302:    |  call(156)
303:    exit()
304:    return()
305:    enter(0)
306:    |  call(254)
307:    exit()
308:    enter(1)
309:    |  call(291)
310:    exit()
311:    enter(2)
312:    |  call(156)
313:    exit()
314:    return()
315:    enter(0)
316:    |  read(long)
317:    |  eval_equal(0)
318:    |  cond_jump(334)
319:    |  eval_greater(0)
320:    |  cond_jump(323)
321:    |  read(UnusedLong)
322:    |  mult_long(-1)
323:    |  push_loop(0)
324:    |  read(string)
325:    |  append_map(0)
326:    |  |  read(string)
327:    |  |  set(string)
328:    |  exit(0)
329:    |  pop_loop(0)
330:    |  add_long(-1)
331:    |  eval_equal(0)
332:    |  cond_jump(316)
333:    |  jump(323)
334:    exit()
335:    enter(1)
336:    |  read(int)
337:    |  set(int)
338:    exit()
339:    return()
340:    enter(0)
341:    |  read(string)
342:    |  set(string)
343:    exit()
344:    return()
345:    enter(0)
346:    |  read(string)
347:    |  set(string)
348:    exit()
349:    enter(1)
350:    |  read(string)
351:    |  set(string)
352:    exit()
353:    enter(2)
354:    |  read(string)
355:    |  set(string)
356:    exit()
357:    enter(3)
358:    |  read(string)
359:    |  set(string)
360:    exit()
361:    enter(4)
362:    |  read(string)
363:    |  set(string)
364:    exit()
365:    enter(5)
366:    |  read(string)
367:    |  set(string)
368:    exit()
369:    enter(6)
370:    |  read(string)
371:    |  set(string)
372:    exit()
373:    enter(7)
374:    |  read(string)
375:    |  set(string)
376:    exit()
377:    enter(8)
378:    |  read(string)
379:    |  set(string)
380:    exit()
381:    enter(9)
382:    |  read(string)
383:    |  set(string)
384:    exit()
385:    enter(10)
386:    |  read(long)
387:    |  eval_equal(0)
388:    |  cond_jump(403)
389:    |  eval_greater(0)
390:    |  cond_jump(393)
391:    |  read(UnusedLong)
392:    |  mult_long(-1)
393:    |  push_loop(0)
394:    |  append_array(0)
395:    |  |  read(string)
396:    |  |  set(string)
397:    |  exit(0)
398:    |  pop_loop(0)
399:    |  add_long(-1)
400:    |  eval_equal(0)
401:    |  cond_jump(386)
402:    |  jump(393)
403:    exit()
404:    return()
405:    enter(0)
406:    |  read(string)
407:    |  set(string)
408:    exit()
409:    enter(1)
410:    |  read(string)
411:    |  set(string)
412:    exit()
413:    enter(2)
414:    |  read(string)
415:    |  set(string)
416:    exit()
417:    enter(3)
418:    |  read(string)
419:    |  set(string)
420:    exit()
421:    enter(4)
422:    |  read(string)
423:    |  set(string)
424:    exit()
425:    enter(5)
426:    |  call(156)
427:    exit()
428:    return()
Error 1:    Unsupported type for union

{"level":"fatal","app":"schema-registry-poc-consumer","env":"dev","git.sha":"","exception":"Panic at pc 18 -  (exit())","context":{},"created":"2021-09-12T13:42:48Z","message":"error reading message"}
tneilturner commented 3 years ago

On a side note -- I'm really interested in your approach to this problem if you would care to describe how the compiler/vm approach works at a high level for deserialization.

Very interesting indeed!

actgardner commented 2 years ago

Hey @tneilturner, I'm still looking into the new error. The compiler/VM idea was a way to add support for schema evolution - originally this library only supported generating serde code for a single schema, and it did it by plugging together a few templated pieces of Go code for "deserialize a data type", "switch on a union type", "loop over the elements of an array/map" and compiling them.

To support schema evolution (and generic data), I wanted to support generating new deserializers at runtime. Now the compiler looks at the reader and writer schemas, and it produces instructions in the same terms as the old generated code (read a value, set a field in the target struct to the last-read value, loop over array contents, etc). The VM takes a generated struct for the reader schema, and a byte stream written with the writer schema, and it just evaluates the instructions to deserialize the data into the struct.

The benefit of splitting up the multiple phases of compilation and evaluation was initially to make it simpler to understand all the evolution edge cases - the compiler should map pretty well to the Avro spec, and the VM handles the specifics of the generated structs. It also amortizes the cost of "compilation" in the case where there's many records with the same schema, becaue the schema evolution rules don't have to be re-evaluated every time.

In retrospect I probably got too cute with the set of instructions and made them very simple, which means the deserializers are pretty large and there's a lot of branching in the VM. Combining instructions and/or making the VM smarter to improve performance is something I've thought about, but I've been focused on correctness issues first.

tneilturner commented 2 years ago

Thanks for continuing to look into this! And thanks for the explanation about how it works. One of these days when I have time I'll have to examine your code more thoroughly.

actgardner commented 2 years ago

@tneilturner I've corrected another issue with generic enums, let me know if v9.1.1 fixes your issue.

tneilturner commented 2 years ago

Hi @actgardner! It works now!!!

Thank you so much 🎉