From 6bc46c54a8f0d8a4040457d7808b88dee6a4c4fe Mon Sep 17 00:00:00 2001 From: den Date: Wed, 29 Jan 2025 21:50:59 +0100 Subject: [PATCH] v1.1.5 - added benc file imports + better schema grammar --- cmd/bencgen/README.md | 286 ++++--- cmd/bencgen/bcd/bcd.go | 22 +- cmd/bencgen/codegens/entry-gen.go | 137 ++-- cmd/bencgen/codegens/golang-gen.go | 320 ++++++-- cmd/bencgen/lexer/lexer.go | 105 ++- cmd/bencgen/main.go | 106 +-- cmd/bencgen/parser/parser.go | 329 ++++---- cmd/bencgen/utils/utils.go | 10 +- codecov.yml | 3 +- testing/complex_data/complex_data.go | 639 +++++++++++++++ testing/complex_data/complex_data_test.go | 761 +++--------------- testing/complex_data/complex_test.go | 138 ---- testing/others/main_others_test.go | 51 -- testing/others/others.go | 284 +++++++ testing/others/others_test.go | 281 +------ testing/person/main_person_test.go | 124 --- testing/person/person.go | 387 +++++++++ .../person/{person2_test.go => person2.go} | 72 +- testing/person/person_test.go | 491 +++-------- testing/schemas/complex_data.benc | 6 +- testing/schemas/others.benc | 29 +- testing/schemas/person.benc | 6 +- testing/schemas/person2.benc | 9 +- 23 files changed, 2477 insertions(+), 2119 deletions(-) create mode 100644 testing/complex_data/complex_data.go delete mode 100644 testing/complex_data/complex_test.go delete mode 100644 testing/others/main_others_test.go create mode 100644 testing/others/others.go delete mode 100644 testing/person/main_person_test.go create mode 100644 testing/person/person.go rename testing/person/{person2_test.go => person2.go} (78%) diff --git a/cmd/bencgen/README.md b/cmd/bencgen/README.md index f39170d..88e563d 100644 --- a/cmd/bencgen/README.md +++ b/cmd/bencgen/README.md @@ -1,25 +1,31 @@ # bencgen -A code generator for Benc, ensuring both forward and backward compatibility. +A code generator for the **Benc** schema format, ensuring forward and backward compatibility of generated code. -## Table of Contents +## Table Of Contents - [Requirements](#requirements) - [Installation](#installation) - [Usage](#usage) -- [Generating Example](#generating-example) -- [Go Usage Example](#go-usage-example) -- [Breaking Changes Detector](#breaking-changes-detector-bcd) + - [Example Usage](#example-usage) +- [Generating Example](#generating-example-specifically-go-because-of-go_package) + - [Go Usage Example](#go-usage-example) +- [Breaking Changes Detector (BCD)](#breaking-changes-detector-bcd) - [Maintaining](#maintaining) - [Examples and Tests](#examples-and-tests) +- [Importing Other Benc Files](#importing-other-benc-files) - [Enums](#enums) - [Schema Grammar](#schema-grammar) + - [Define](#define) + - [Fields](#fields) + - [Types](#types) + - [Containers or Enums](#containers-or-enums) - [Languages](#languages) - [License](#license) ## Requirements -- Go (for installing and running `bencgen`) +- **Go** (for installing and running `bencgen`) - [Benc Standard](../../std/README.md) - [Bencgen Implementation](../../impl/gen/README.md) @@ -27,66 +33,79 @@ A code generator for Benc, ensuring both forward and backward compatibility. 1. Install `bencgen` using the following command: -```bash -go install github.com/deneonet/benc/cmd/bencgen -``` + ```bash + go install github.com/deneonet/benc/cmd/bencgen + ``` ## Usage -Arguments: +### Arguments + +- `--in`: Comma-separated list of input `.benc` files (required, no spaces allowed) +- `--out`: Output directory (optional; use `...` to replace with input filename) +- `--lang`: Target [language](#languages) to compile into (required) +- `--file`: Name of the output file (optional; use `...` to replace with input filename) +- `--force`: Disable the breaking changes detector (optional, not recommended in production) +- `--import-dir`: Comma-separated list of directories to import files from (optional, no spaces allowed) + +Find a complex bencgen usage example [here](#importing-other-benc-files). -- `--in`: The input `.benc` file (required) -- `--out`: The output directory (optional) -- `--lang`: The target [language](#languages) to compile into (required) -- `--file`: The name of the output file (optional) -- `--force`: Disable the breaking changes detector (optional, not recommended if the schema is in use, e.g., in software) +### Example Usage -## Generating Example +```bash +bencgen --in person.benc --lang go --out ./output --file ..._result +``` + +This command will process the `person.benc` file, generate Go code, and save the result as `person_result.go` in the `output` directory. + +## Generating Example (specifically go, because of go_package) 1. Create a `.benc` file (e.g., `person.benc`). 2. Write a schema, for example: ```plaintext - header person; + define person; + + var go_package = "github.com/.../output/person"; ctr Person { - byte age = 1; + int age = 1; string name = 2; Parents parents = 3; Child child = 4; } ctr Child { - byte age = 1; + int age = 1; string name = 2; Parents parents = 3; } - ctr Parents { - string mother = 1; - string father = 2; - } + ctr Parents { + string mother = 1; + string father = 2; + } ``` 3. Generate Go code with the following command: -```bash -bencgen --in person.benc --lang go -``` + ```bash + bencgen --in person.benc --lang go --out ./output/person --file ... + ``` 4. Follow the instructions for using the generated code in the selected language: - [Go Usage Example](#go-usage-example) -## Go Usage Example +### Go Usage Example -After generating, a file called `out/person.benc.go` will be created. To marshal and unmarshal the `Person` data: +After generating the code, a file called `output/person/person.go` will be created. Here's how to marshal and unmarshal the `Person` data: ```go package main import ( "github.com/deneonet/benc" - person ".../out" + "github.com/.../output/person" ) func main() { @@ -119,40 +138,40 @@ func main() { ## Breaking Changes Detector (BCD) -BCD detects breaking changes, such as: +BCD helps identify breaking changes, such as: - A field exists but is marked as reserved. -- A field was removed but is not marked as reserved. -- The type of a field changed, but its ID remained the same. - -## Maintaining +- A field was removed but isn't marked as reserved. +- The type of a field changed, but its ID remains the same. -To maintain your Benc schema, follow these rules: +## Maintaining Your Schema -- Mark removed fields as reserved. -- New fields must be appended at the bottom (fields should be ordered by their IDs in ascending order). -- If the type of a field changes, assign it a new ID and mark the old ID as reserved. -- Use [BCD](#breaking-changes-detector-bcd) (enabled by default) to catch and report compatibility issues. +To ensure forward and backward compatibility in your Benc schema, follow these best practices: -### Reserving IDs +- **Mark removed fields as reserved.** +- **Append new fields at the bottom** (order fields by their IDs in ascending order). +- If a field's type changes, **assign it a new ID** and mark the old ID as reserved. +- Use the **[BCD](#breaking-changes-detector-bcd)** (enabled by default) to catch and report compatibility issues. -For example, using the `person` schema from the [earlier section](#generating-example), if the `parents` field is removed (ID `3`), mark ID `3` as reserved: +### Reserving IDs Example -`person.benc`: +If the `parents` field (ID `3`) is removed, you should mark the ID as reserved: ```plaintext -header person; +define person; + +var go_package = "github.com/.../output/person"; ctr Person { reserved 3; # Reserved the 'parents' field ID - byte age = 1; + int age = 1; string name = 2; Child child = 4; } ctr Child { - byte age = 1; + int age = 1; string name = 2; Parents parents = 3; } @@ -165,15 +184,86 @@ ctr Parents { ## Examples and Tests -See all tests [here](../../testing). -For tests specifically related to forward and backward compatibility, see [here](../../testing/person/main_person_test.go). +See all tests [here](../../testing). For tests related to forward and backward compatibility, check [here](../../testing/person/main_person_test.go). + +## Importing Other Benc Files + +To reuse Benc schemas across multiple files, you can **import** other schemas using the `use` keyword. + +### Example: Importing Files + +Assume you have the following structure: + +``` +/schemas + /baby.benc + /babysitter.benc + /parent.benc +``` + +**baby.benc:** + +```plaintext +define baby.v1; + +var go_package = "github.com/.../output/baby"; + +ctr Baby { + int age = 1; + string name = 2; +} +``` + +**babysitter.benc:** + +```plaintext +define babysitter; + +use "baby.benc"; + +var go_package = "github.com/.../output/babysitter"; + +ctr Babysitter { + int age = 1; + string name = 2; + baby.v1.Baby babyAssignedTo = 3; +} +``` + +**parent.benc:** + +```plaintext +define parent; + +use "baby.benc"; + +var go_package = "github.com/.../output/parent"; + +ctr Parent { + int age = 1; + string name = 2; + baby.v1.Baby baby = 3; +} +``` + +To generate the code for all three files: + +```bash +bencgen --in schemas/baby.benc,schemas/babysitter.benc,schemas/parent.benc --out output/... --file ... --lang go --import-dir schemas +``` + +Now, both `babysitter` and `parent` share the same `baby` data. ## Enums -Enums example: +Enums are treated as named integers. Forward and backward compatibility is preserved, even when fields are added or removed from an enum. + +### Enum Example: ```plaintext -header person; +define person; + +var go_package = "github.com/.../output/person"; enum JobStatus { Employed, @@ -181,32 +271,40 @@ enum JobStatus { } ctr Person { - byte age = 1; + int age = 1; string name = 2; JobStatus jobStatus = 3; } ``` -Enums are treated as named integers. Forward and backward compatibility is preserved even when fields are added or removed from an enum, as the benc protocol doesn't rely on them. - ## Schema Grammar A schema consists of the following components: -### Header +### Define -A header consists of: `header` IDENTIFIER `;` +The `define` statement is used when importing other Benc files to access their enums/containers: -| **Benc** | **Go** | -| :----------: | :-----------: | -| `header ...` | `package ...` | +```plaintext +define ; +``` ### Fields -A field consists of: "[ATTR](#type-attributes) [TYPE](#types) IDENTIFIER = ID ;" || "[CONTAINER_OR_ENUM_NAME](#containers-or-enums) IDENTIFIER = ID ;" +A field consists of: + +```plaintext +[ATTR] [TYPE] IDENTIFIER = ID; +``` + +or + +```plaintext +[CONTAINER_OR_ENUM_NAME] IDENTIFIER = ID; +``` -- The ID must be no larger than `65535`. -- A field of type `string` may have [type attributes](#type-attributes). +- **ID**: Must be no larger than `65535`. +- **Type attributes** (e.g., `unsafe`) precede the type. Example of a simple field: @@ -217,49 +315,45 @@ string name = 1; Example of a field with type attributes: ```plaintext -@unsafe string name = 1; +unsafe string name = 1; ``` -**Note:** Type attributes **must** precede the type, e.g., for arrays: +Type attributes **must** precede the type. For arrays: ```plaintext -[] @unsafe string names = 1; +[] unsafe string names = 1; ``` -#### Type Attributes - -- **unsafe** (Go only): Uses the `unsafe` package, allowing faster unmarshalling operations. Multiple `unsafe` attributes are ignored. - -## Types - -| **Benc** | **Go** | -| :-------: | :-------: | -| `byte` | `byte` | -| `bytes` | `[]byte` | -| `int` | `int` | -| `int16` | `int16` | -| `int32` | `int32` | -| `int64` | `int64` | -| `uint` | `uint` | -| `uint16` | `uint16` | -| `uint32` | `uint32` | -| `uint64` | `uint64` | -| `float32` | `float32` | -| `float64` | `float64` | -| `bool` | `bool` | -| `string` | `string` | -| `[]T` | `[]T` | -| `` | `map[K]V` | - -### Containers Or Enums +### Types + +| **Benc** | **Golang** | +| :-------: | :--------: | +| `byte` | `byte` | +| `bytes` | `[]byte` | +| `int` | `int` | +| `int16` | `int16` | +| `int32` | `int32` | +| `int64` | `int64` | +| `uint` | `uint` | +| `uint16` | `uint16` | +| `uint32` | `uint32` | +| `uint64` | `uint64` | +| `float32` | `float32` | +| `float64` | `float64` | +| `bool` | `bool` | +| `string` | `string` | +| `[]T` | `[]T` | +| `` | `map[K]V` | + +### Containers or Enums A container or enum name refers to another defined structure or container. -**Container**: +**Container Example:** -``` +```plaintext ctr Person { - byte age = 1; + int age = 1; string name = 2; Child child = 4; } @@ -267,15 +361,15 @@ ctr Person { Reference: -``` +```plaintext ctr Person2 { Person person = 1; } ``` -**Enum**: +**Enum Example:** -``` +```plaintext enum JobStatus { Employed, Unemployed @@ -284,7 +378,7 @@ enum JobStatus { Reference: -``` +```plaintext ctr Person { JobStatus jobStatus = 1; } diff --git a/cmd/bencgen/bcd/bcd.go b/cmd/bencgen/bcd/bcd.go index db93c5a..70811be 100644 --- a/cmd/bencgen/bcd/bcd.go +++ b/cmd/bencgen/bcd/bcd.go @@ -67,10 +67,10 @@ func (b *Bcd) buildMsgs(existingMsgs Msgs, force bool) Msgs { newMsgs := Msgs{Msgs: make(map[string]Msg)} for _, node := range b.Nodes { - if stmt, ok := node.(*parser.CtrStmt); ok { + if stmt, ok := node.(*parser.ContainerStmt); ok { fields := make(map[uint16]parser.Field) for _, field := range stmt.Fields { - fields[field.Id] = field + fields[field.ID] = field } if existingMsg, exists := existingMsgs.Msgs[stmt.Name]; !force && exists { @@ -79,7 +79,7 @@ func (b *Bcd) buildMsgs(existingMsgs Msgs, force bool) Msgs { newMsgs.Msgs[stmt.Name] = Msg{ Fields: fields, - ReservedIDs: stmt.ReservedIds, + ReservedIDs: stmt.ReservedIDs, } } } @@ -88,20 +88,20 @@ func (b *Bcd) buildMsgs(existingMsgs Msgs, force bool) Msgs { return newMsgs } -func (b *Bcd) checkForConflicts(existingMsg Msg, stmt *parser.CtrStmt, fields map[uint16]parser.Field) { +func (b *Bcd) checkForConflicts(existingMsg Msg, stmt *parser.ContainerStmt, fields map[uint16]parser.Field) { for _, existingField := range existingMsg.Fields { - currentField, exists := fields[existingField.Id] - if !exists && !slices.Contains(stmt.ReservedIds, existingField.Id) { - b.handleError(fmt.Sprintf("Field \"%s\" (id \"%d\") on msg \"%s\" was removed, but \"%d\" is not marked as reserved.", existingField.Name, existingField.Id, stmt.Name, existingField.Id)) + currentField, exists := fields[existingField.ID] + if !exists && !slices.Contains(stmt.ReservedIDs, existingField.ID) { + b.handleError(fmt.Sprintf("Field '%s' (id '%d') on msg '%s' was removed, but '%d' is not marked as reserved.", existingField.Name, existingField.ID, stmt.Name, existingField.ID)) } if exists { - if slices.Contains(stmt.ReservedIds, currentField.Id) { - b.handleError(fmt.Sprintf("Field \"%s\" (id \"%d\") on msg \"%s\" may not be marked as reserved.", currentField.Name, currentField.Id, stmt.Name)) + if slices.Contains(stmt.ReservedIDs, currentField.ID) { + b.handleError(fmt.Sprintf("Field '%s' (id '%d') on msg '%s' may not be marked as reserved.", currentField.Name, currentField.ID, stmt.Name)) } - if existingField.Id == currentField.Id && !utils.CompareTypes(existingField.Type, currentField.Type) { - b.handleError(fmt.Sprintf("Field \"%s\" (id \"%d\") on msg \"%s\" changed type from \"%s\" to \"%s\".", currentField.Name, currentField.Id, stmt.Name, utils.FormatType(existingField.Type), utils.FormatType(currentField.Type))) + if existingField.ID == currentField.ID && !utils.CompareTypes(existingField.Type, currentField.Type) { + b.handleError(fmt.Sprintf("Field '%s' (id '%d') on msg '%s' changed type from '%s' to '%s'.", currentField.Name, currentField.ID, stmt.Name, utils.FormatType(existingField.Type), utils.FormatType(currentField.Type))) } } } diff --git a/cmd/bencgen/codegens/entry-gen.go b/cmd/bencgen/codegens/entry-gen.go index 51655b3..e8c3146 100644 --- a/cmd/bencgen/codegens/entry-gen.go +++ b/cmd/bencgen/codegens/entry-gen.go @@ -28,7 +28,7 @@ type Gen interface { File() string Lang() GenLang - GenHeader() string + GenDefine() string GenEnum() string GenStruct() string GenReservedIds() string @@ -39,14 +39,18 @@ type Gen interface { GenMarshalPlain() string GenUnmarshalPlain() string - HasHeader() bool + ProcessImport(stmt *parser.UseStmt, importDirs []string) ([]string, []string) - SetCtrDecls(ctrDecls []string) - SetEnumDecls(ctrDecls []string) + SetVarMap(map[string]string) + + HasPackageDefined() bool + + AddEnumDecls(enumDecls []string) + AddContainerDecls(containerDecls []string) - SetCtrStatement(stmt *parser.CtrStmt) SetEnumStatement(stmt *parser.EnumStmt) - SetHeaderStatement(stmt *parser.HeaderStmt) + SetDefineStatement(stmt *parser.DefineStmt) + SetContainerStatement(stmt *parser.ContainerStmt) } func NewGen(lang GenLang, file string) Gen { @@ -58,7 +62,7 @@ func NewGen(lang GenLang, file string) Gen { } } -func logErrorAndExit(g Gen, msg string) { +func LogErrorAndExit(g Gen, msg string) { fmt.Printf("\n\033[1;31m[bencgen] Error:\033[0m\n"+ " \033[1;37mFile:\033[0m %s\n"+ " \033[1;37mMessage:\033[0m %s\n", g.File(), msg) @@ -67,119 +71,138 @@ func logErrorAndExit(g Gen, msg string) { var disallowedNames = []string{"b", "n", "id", "r"} -func Generate(g Gen, nodes []parser.Node) string { - ctrDecls := []string{} +func Generate(g Gen, nodes []parser.Node, importDirs []string) string { enumDecls := []string{} + containerDecls := []string{} + + varMap := make(map[string]string) res := fmt.Sprintf("// Code generated by bencgen %s. DO NOT EDIT.\n// source: %s\n\n", g.Lang().String(), g.File()) for _, node := range nodes { switch stmt := node.(type) { - case *parser.CtrStmt: - validateCtrStmt(g, stmt, enumDecls, ctrDecls) - ctrDecls = append(ctrDecls, stmt.Name) + case *parser.UseStmt: + aEnumDecls, aContainerDecls := g.ProcessImport(stmt, importDirs) + enumDecls = append(enumDecls, aEnumDecls...) + containerDecls = append(containerDecls, aContainerDecls...) + } + } + + for _, node := range nodes { + switch stmt := node.(type) { case *parser.EnumStmt: - validateEnumStmt(g, stmt, enumDecls, ctrDecls) + validateEnumStmt(g, stmt, enumDecls, containerDecls) enumDecls = append(enumDecls, stmt.Name) + case *parser.ContainerStmt: + validateCtrStmt(g, stmt, enumDecls, containerDecls) + containerDecls = append(containerDecls, stmt.Name) + case *parser.VarStmt: + varMap[stmt.Name] = stmt.Value } } - g.SetCtrDecls(ctrDecls) - g.SetEnumDecls(enumDecls) + g.AddEnumDecls(enumDecls) + g.AddContainerDecls(containerDecls) + + g.SetVarMap(varMap) for _, node := range nodes { switch stmt := node.(type) { - case *parser.HeaderStmt: - if g.HasHeader() { - logErrorAndExit(g, "Multiple 'header' declarations.") + case *parser.DefineStmt: + if g.HasPackageDefined() { + LogErrorAndExit(g, "Multiple packages defined ( 'define ...' ).") } - g.SetHeaderStatement(stmt) - res += g.GenHeader() - case *parser.CtrStmt: - if !g.HasHeader() { - logErrorAndExit(g, "A 'header' was not declared.") - } - validateContainerFields(g, stmt, ctrDecls, enumDecls) - - g.SetCtrStatement(stmt) - res += generateCtr(g) + g.SetDefineStatement(stmt) + res += g.GenDefine() case *parser.EnumStmt: - if !g.HasHeader() { - logErrorAndExit(g, "A 'header' was not declared.") + if !g.HasPackageDefined() { + LogErrorAndExit(g, "A package was not defined ( 'define ...' ).") } validateEnumFields(g, stmt) g.SetEnumStatement(stmt) res += g.GenEnum() + case *parser.ContainerStmt: + if !g.HasPackageDefined() { + LogErrorAndExit(g, "A package was not defined ( 'define ...' ).") + } + validateContainerFields(g, stmt, containerDecls, enumDecls) + + g.SetContainerStatement(stmt) + res += generateContainer(g) } } return res } -func validateCtrStmt(g Gen, stmt *parser.CtrStmt, enumDecls []string, ctrDecls []string) { +func validateCtrStmt(g Gen, stmt *parser.ContainerStmt, enumDecls []string, containerDecls []string) { if slices.Contains(enumDecls, stmt.Name) { - logErrorAndExit(g, fmt.Sprintf("A enum with the same name \"%s\" is already declared.", stmt.Name)) + LogErrorAndExit(g, fmt.Sprintf("A enum with the same name '%s' is already declared.", stmt.Name)) } - if slices.Contains(ctrDecls, stmt.Name) { - logErrorAndExit(g, fmt.Sprintf("Multiple containers with the same name \"%s\".", stmt.Name)) + if slices.Contains(containerDecls, stmt.Name) { + LogErrorAndExit(g, fmt.Sprintf("Multiple containers with the same name '%s'.", stmt.Name)) } if len(stmt.Fields) == 0 { - logErrorAndExit(g, fmt.Sprintf("Empty container \"%s\".", stmt.Name)) + LogErrorAndExit(g, fmt.Sprintf("Empty container '%s'.", stmt.Name)) } } -func validateEnumStmt(g Gen, stmt *parser.EnumStmt, enumDecls []string, ctrDecls []string) { +func validateEnumStmt(g Gen, stmt *parser.EnumStmt, enumDecls []string, containerDecls []string) { if slices.Contains(enumDecls, stmt.Name) { - logErrorAndExit(g, fmt.Sprintf("Multiple enums with the same name \"%s\".", stmt.Name)) + LogErrorAndExit(g, fmt.Sprintf("Multiple enums with the same name '%s'.", stmt.Name)) } - if slices.Contains(ctrDecls, stmt.Name) { - logErrorAndExit(g, fmt.Sprintf("A container with the same name \"%s\" is already declared.", stmt.Name)) + if slices.Contains(containerDecls, stmt.Name) { + LogErrorAndExit(g, fmt.Sprintf("A container with the same name '%s' is already declared.", stmt.Name)) } - if len(stmt.Fields) == 0 { - logErrorAndExit(g, fmt.Sprintf("Empty enum \"%s\".", stmt.Name)) + if slices.Contains(disallowedNames, utils.ToLower(stmt.Name)) { + LogErrorAndExit(g, fmt.Sprintf("Disallowed enum name '%s'.", stmt.Name)) + } + + if len(stmt.Values) == 0 { + LogErrorAndExit(g, fmt.Sprintf("Empty enum '%s'.", stmt.Name)) } } -func validateContainerFields(g Gen, stmt *parser.CtrStmt, ctrDecls []string, enumDecls []string) { +func validateContainerFields(g Gen, stmt *parser.ContainerStmt, enumDecls []string, containerDecls []string) { var ids []uint16 var lastID uint16 var fieldNames []string for _, field := range stmt.Fields { _, enumNotFound := utils.FindUndeclaredContainersOrEnums(enumDecls, field.Type) - if ctrEnum, notFound := utils.FindUndeclaredContainersOrEnums(ctrDecls, field.Type); notFound && enumNotFound { - logErrorAndExit(g, fmt.Sprintf("Container/Enum \"%s\" not declared on \"%s\" (\"%s\").", ctrEnum, stmt.Name, field.Name)) + if ctrEnum, notFound := utils.FindUndeclaredContainersOrEnums(containerDecls, field.Type); notFound && enumNotFound { + LogErrorAndExit(g, fmt.Sprintf("Container/Enum '%s' not declared on '%s' ('%s').", ctrEnum, stmt.Name, field.Name)) } - if field.Id == 0 { - logErrorAndExit(g, fmt.Sprintf("Field \"%s\" has an ID of \"0\" on \"%s\".", field.Name, stmt.Name)) + if field.ID == 0 { + LogErrorAndExit(g, fmt.Sprintf("Field '%s' has an ID of '0' on '%s'.", field.Name, stmt.Name)) } - if slices.Contains(ids, field.Id) { - logErrorAndExit(g, fmt.Sprintf("Multiple fields with the same ID \"%d\" on \"%s\".", field.Id, stmt.Name)) + if slices.Contains(ids, field.ID) { + LogErrorAndExit(g, fmt.Sprintf("Multiple fields with the same ID '%d' on '%s'.", field.ID, stmt.Name)) } - if lastID > field.Id { - logErrorAndExit(g, fmt.Sprintf("Fields must be ordered by their IDs in ascending order on \"%s\".", stmt.Name)) + if lastID > field.ID { + LogErrorAndExit(g, fmt.Sprintf("Fields must be ordered by their IDs in ascending order on '%s'.", stmt.Name)) } if slices.Contains(fieldNames, field.Name) { - logErrorAndExit(g, fmt.Sprintf("Multiple fields with the same name \"%s\" on \"%s\".", field.Name, stmt.Name)) + LogErrorAndExit(g, fmt.Sprintf("Multiple fields with the same name '%s' on '%s'.", field.Name, stmt.Name)) } if slices.Contains(disallowedNames, utils.ToLower(stmt.Name)) { - logErrorAndExit(g, fmt.Sprintf("Unallowed container name \"%s\".", stmt.Name)) + LogErrorAndExit(g, fmt.Sprintf("Disallowed container name '%s'.", stmt.Name)) } - lastID = field.Id - ids = append(ids, field.Id) + lastID = field.ID + ids = append(ids, field.ID) fieldNames = append(fieldNames, field.Name) } } @@ -187,15 +210,15 @@ func validateContainerFields(g Gen, stmt *parser.CtrStmt, ctrDecls []string, enu func validateEnumFields(g Gen, stmt *parser.EnumStmt) { var fieldNames []string - for _, field := range stmt.Fields { + for _, field := range stmt.Values { if slices.Contains(fieldNames, field) { - logErrorAndExit(g, fmt.Sprintf("Multiple fields with the same name \"%s\" on \"%s\".", field, stmt.Name)) + LogErrorAndExit(g, fmt.Sprintf("Multiple values '%s' on '%s'.", field, stmt.Name)) } fieldNames = append(fieldNames, field) } } -func generateCtr(g Gen) string { +func generateContainer(g Gen) string { return g.GenStruct() + g.GenReservedIds() + g.GenSize() + diff --git a/cmd/bencgen/codegens/golang-gen.go b/cmd/bencgen/codegens/golang-gen.go index de0f8bc..bd2e8a3 100644 --- a/cmd/bencgen/codegens/golang-gen.go +++ b/cmd/bencgen/codegens/golang-gen.go @@ -2,22 +2,25 @@ package codegens import ( "fmt" + "os" + "path/filepath" "slices" "strings" "github.com/deneonet/benc/cmd/bencgen/lexer" "github.com/deneonet/benc/cmd/bencgen/parser" "github.com/deneonet/benc/cmd/bencgen/utils" + "golang.org/x/exp/maps" ) -type GoCtrStmt struct { +type GoContainerStmt struct { PublicName string PrivateName string DefaultName string Fields []parser.Field - ReservedIds []uint16 + ReservedIDs []uint16 } type GoEnumStmt struct { @@ -26,11 +29,11 @@ type GoEnumStmt struct { DefaultName string - Fields []string + Values []string } type GoField struct { - Id uint16 + ID uint16 PublicName string PrivateName string @@ -46,21 +49,26 @@ func (f *GoField) AppendUnsafeIfPresent() string { type GoGen struct { file string - ctrDecls []string - enumDecls []string + enumDecls []string + containerDecls []string + + varMap map[string]string + + importedPackages []string + importedEnumsOrContainers map[string]string plainGen bool - headerStmt *parser.HeaderStmt + defineStmt *parser.DefineStmt // currently generated... - field GoField - ctrStmt GoCtrStmt - enumStmt GoEnumStmt + field GoField + enumStmt GoEnumStmt + containerStmt GoContainerStmt } func NewGoGen(file string) *GoGen { - return &GoGen{file: file} + return &GoGen{file: file, importedEnumsOrContainers: make(map[string]string)} } func (g *GoGen) File() string { @@ -71,18 +79,18 @@ func (*GoGen) Lang() GenLang { return GoGenLang } -func (g *GoGen) IsCtr(extStructureName string) bool { - return slices.Contains(g.ctrDecls, extStructureName) +func (g *GoGen) IsEnum(externalStructure string) bool { + return slices.Contains(g.enumDecls, externalStructure) } -func (g *GoGen) IsEnum(extStructureName string) bool { - return slices.Contains(g.enumDecls, extStructureName) +func (g *GoGen) IsContainer(externalStructure string) bool { + return slices.Contains(g.containerDecls, externalStructure) } func (g *GoGen) ForEachCtrFields(f func(i int)) { - for i, field := range g.ctrStmt.Fields { + for i, field := range g.containerStmt.Fields { g.field = GoField{ - Id: field.Id, + ID: field.ID, PublicName: utils.ToUpper(field.Name), PrivateName: utils.ToLower(field.Name), @@ -94,59 +102,197 @@ func (g *GoGen) ForEachCtrFields(f func(i int)) { } } -func (g *GoGen) ForEachEnumFields(f func(i int, field string)) { - for i, field := range g.enumStmt.Fields { - f(i, utils.ToUpper(field)) +func (g *GoGen) ForEachEnumValues(f func(i int, value string)) { + for i, value := range g.enumStmt.Values { + f(i, utils.ToUpper(value)) } } -func (g *GoGen) HasHeader() bool { - return g.headerStmt != nil +func (g *GoGen) HasPackageDefined() bool { + return g.defineStmt != nil +} + +func (g *GoGen) SetVarMap(varMap map[string]string) { + g.varMap = varMap } -func (g *GoGen) SetCtrStatement(stmt *parser.CtrStmt) { - g.ctrStmt = GoCtrStmt{ +func (g *GoGen) SetDefineStatement(stmt *parser.DefineStmt) { + g.defineStmt = stmt +} + +func (g *GoGen) SetEnumStatement(stmt *parser.EnumStmt) { + g.enumStmt = GoEnumStmt{ PublicName: utils.ToUpper(stmt.Name), PrivateName: utils.ToLower(stmt.Name), DefaultName: stmt.Name, - Fields: stmt.Fields, - ReservedIds: stmt.ReservedIds, + Values: stmt.Values, } } -func (g *GoGen) SetEnumStatement(stmt *parser.EnumStmt) { - g.enumStmt = GoEnumStmt{ +func (g *GoGen) adjustExternalStructureToImports(t *parser.Type) { + if t.IsAnExternalStructure() { + if replacement, ok := g.importedEnumsOrContainers[t.ExternalStructure]; ok { + t.ExternalStructure = replacement + } + return + } + + if t.IsArray { + g.adjustExternalStructureToImports(t.ChildType) + return + } + + if t.IsMap { + g.adjustExternalStructureToImports(t.MapKeyType) + g.adjustExternalStructureToImports(t.ChildType) + return + } +} + +func (g *GoGen) SetContainerStatement(stmt *parser.ContainerStmt) { + fields := stmt.Fields + for _, field := range fields { + g.adjustExternalStructureToImports(field.Type) + } + + g.containerStmt = GoContainerStmt{ PublicName: utils.ToUpper(stmt.Name), PrivateName: utils.ToLower(stmt.Name), + Fields: fields, DefaultName: stmt.Name, - Fields: stmt.Fields, + ReservedIDs: stmt.ReservedIDs, } } -func (g *GoGen) SetHeaderStatement(stmt *parser.HeaderStmt) { - g.headerStmt = stmt +func (g *GoGen) AddEnumDecls(enumDecls []string) { + g.enumDecls = append(g.enumDecls, enumDecls...) +} + +func (g *GoGen) AddContainerDecls(containerDecls []string) { + g.containerDecls = append(g.containerDecls, containerDecls...) } -func (g *GoGen) SetCtrDecls(ctrDecls []string) { - g.ctrDecls = ctrDecls +func (g *GoGen) ProcessImport(stmt *parser.UseStmt, importDirs []string) ([]string, []string) { + var content []byte + var err error + + importDirs = append(importDirs, "./") + + for _, importDir := range importDirs { + trimmedDir := strings.TrimSuffix(importDir, "/") + fullPath := filepath.Join(trimmedDir, stmt.Path) + + if _, err = os.Stat(fullPath); os.IsNotExist(err) { + continue + } + + content, err = os.ReadFile(fullPath) + if err == nil { + break + } + } + + if err != nil { + LogErrorAndExit(g, fmt.Sprintf("Failed to read file: %s. Check again whether your import dirs are correct.", stmt.Path)) + } + + importParser := parser.NewParser(strings.NewReader(string(content)), string(content)) + importNodes := importParser.Parse() + + var goPackage string + var definePackage string + + var enumDecls = []string{} + var containerDecls = []string{} + + for _, node := range importNodes { + switch n := node.(type) { + case *parser.VarStmt: + if n.Name == "go_package" { + goPackage = n.Value + } + case *parser.DefineStmt: + definePackage = n.Package + case *parser.EnumStmt: + enumDecls = append(enumDecls, n.Name) + case *parser.ContainerStmt: + containerDecls = append(containerDecls, n.Name) + } + } + + if goPackage == "" { + LogErrorAndExit(g, fmt.Sprintf("No 'go_package' variable has been set in imported file '%s'.", stmt.Path)) + } + + splitPackage := strings.Split(goPackage, "/") + if len(splitPackage) <= 1 { + LogErrorAndExit(g, fmt.Sprintf("Invalid 'go_package' variable has been set in imported file '%s'.", stmt.Path)) + } + + packageAlias := splitPackage[len(splitPackage)-1] + + importedEnums := make(map[string]string) + importedContainers := make(map[string]string) + + for _, enum := range enumDecls { + importedEnums[definePackage+"."+enum] = packageAlias + "." + enum + } + for _, container := range containerDecls { + importedContainers[definePackage+"."+container] = packageAlias + "." + container + } + + g.enumDecls = append(g.enumDecls, maps.Values(importedEnums)...) + g.containerDecls = append(g.containerDecls, maps.Values(importedContainers)...) + + if !slices.Contains(g.importedPackages, goPackage) { + g.importedPackages = append(g.importedPackages, goPackage) + } + + maps.Copy(g.importedEnumsOrContainers, importedEnums) + maps.Copy(g.importedEnumsOrContainers, importedContainers) + + return maps.Keys(importedEnums), maps.Keys(importedContainers) } -func (g *GoGen) SetEnumDecls(enumDecls []string) { - g.enumDecls = enumDecls +func (g *GoGen) joinImportedPackages() string { + var sb strings.Builder + iEnd := len(g.importedPackages) - 1 + for i, pkg := range g.importedPackages { + if i == iEnd { + sb.WriteString(fmt.Sprintf(" \"%s\"", pkg)) + break + } + sb.WriteString(fmt.Sprintf(" \"%s\"\n", pkg)) + } + return sb.String() } -func (g *GoGen) GenHeader() string { +func (g *GoGen) GenDefine() string { + goPackage, found := g.varMap["go_package"] + if !found { + LogErrorAndExit(g, "No 'go_package' variable has been set.") + } + + splitPackage := strings.Split(goPackage, "/") + if len(splitPackage) <= 1 { + LogErrorAndExit(g, "Invalid 'go_package' variable has been set.") + } + + packageAlias := splitPackage[len(splitPackage)-1] + return fmt.Sprintf( `package %s import ( "github.com/deneonet/benc/std" "github.com/deneonet/benc/impl/gen" + +%s ) -`, g.headerStmt.Name) +`, packageAlias, g.joinImportedPackages()) } func joinUint16(ids []uint16) string { @@ -161,14 +307,14 @@ func joinUint16(ids []uint16) string { } func (g *GoGen) GenReservedIds() string { - ctr := g.ctrStmt + ctr := g.containerStmt return fmt.Sprintf("// Reserved Ids - %s\nvar %sRIds = []uint16{%s}\n\n", - ctr.DefaultName, ctr.PrivateName, joinUint16(ctr.ReservedIds)) + ctr.DefaultName, ctr.PrivateName, joinUint16(ctr.ReservedIDs)) } func (g *GoGen) GenStruct() string { var sb strings.Builder - ctr := g.ctrStmt + ctr := g.containerStmt sb.WriteString(fmt.Sprintf("// Struct - %s\ntype %s struct {\n", ctr.DefaultName, ctr.PublicName)) @@ -190,14 +336,14 @@ func (g *GoGen) GenEnum() string { sb.WriteString(fmt.Sprintf("// Enum - %s\ntype %s int\nconst (\n", enum.DefaultName, enum.PublicName)) - g.ForEachEnumFields(func(i int, field string) { + g.ForEachEnumValues(func(i int, value string) { if i == 0 { sb.WriteString(fmt.Sprintf(" %s%s %s = iota\n", - enum.PublicName, field, enum.PublicName)) + enum.PublicName, value, enum.PublicName)) return } sb.WriteString(fmt.Sprintf(" %s%s\n", - enum.PublicName, field)) + enum.PublicName, value)) }) sb.WriteString(")\n\n") @@ -205,7 +351,7 @@ func (g *GoGen) GenEnum() string { } func (g *GoGen) getSizeFunc() string { - ctr := g.ctrStmt + ctr := g.containerStmt field := g.field switch { @@ -215,8 +361,8 @@ func (g *GoGen) getSizeFunc() string { case field.Type.IsMap: return fmt.Sprintf("bstd.SizeMap(%s.%s, %s, %s)", ctr.PrivateName, field.PublicName, g.getElemSizeFunc(field.Type.MapKeyType), g.getElemSizeFunc(field.Type.ChildType)) - case field.Type.ExtStructure != "": - if g.IsEnum(field.Type.ExtStructure) { + case field.Type.IsAnExternalStructure(): + if g.IsEnum(field.Type.ExternalStructure) { return fmt.Sprintf("bgenimpl.SizeEnum(%s.%s)", ctr.PrivateName, field.PublicName) } @@ -225,8 +371,8 @@ func (g *GoGen) getSizeFunc() string { return fmt.Sprintf("%s.%s.SizePlain()", ctr.PrivateName, field.PublicName) } - return fmt.Sprintf("%s.%s.size(%d)", - ctr.PrivateName, field.PublicName, field.Id) + return fmt.Sprintf("%s.%s.NestedSize(%d)", + ctr.PrivateName, field.PublicName, field.ID) default: switch field.Type.TokenType { case lexer.STRING, lexer.BYTES, lexer.INT, lexer.UINT: @@ -247,13 +393,13 @@ func (g *GoGen) getElemSizeFunc(t *parser.Type) string { case t.IsMap: return fmt.Sprintf("func (s %s) int { return bstd.SizeMap(s, %s, %s) }", utils.BencTypeToGolang(t), g.getElemSizeFunc(t.MapKeyType), g.getElemSizeFunc(t.ChildType)) - case t.ExtStructure != "": - if g.IsEnum(t.ExtStructure) { + case t.IsAnExternalStructure(): + if g.IsEnum(t.ExternalStructure) { return "bgenimpl.SizeEnum" } return fmt.Sprintf("func (s %s) int { return s.SizePlain() }", - utils.ToUpper(t.ExtStructure)) + utils.ToUpper(t.ExternalStructure)) default: return "bstd.Size" + t.TokenType.String() } @@ -261,25 +407,25 @@ func (g *GoGen) getElemSizeFunc(t *parser.Type) string { func (g *GoGen) GenSize() string { var sb strings.Builder - ctr := g.ctrStmt + ctr := g.containerStmt - sb.WriteString(fmt.Sprintf("// Size - %s\nfunc (%s *%s) Size() int {\n return %s.size(0)\n}\n\n", + sb.WriteString(fmt.Sprintf("// Size - %s\nfunc (%s *%s) Size() int {\n return %s.NestedSize(0)\n}\n\n", ctr.DefaultName, ctr.PrivateName, ctr.PublicName, ctr.PrivateName)) - sb.WriteString(fmt.Sprintf("// Nested Size - %s\nfunc (%s *%s) size(id uint16) (s int) {\n", + sb.WriteString(fmt.Sprintf("// Nested Size - %s\nfunc (%s *%s) NestedSize(id uint16) (s int) {\n", ctr.DefaultName, ctr.PrivateName, ctr.PublicName)) g.ForEachCtrFields(func(_ int) { field := g.field tagSize := 2 - if g.field.Id > 255 { + if g.field.ID > 255 { tagSize = 3 } sb.WriteString(fmt.Sprintf(" s += %s", g.getSizeFunc())) - if !g.IsCtr(field.Type.ExtStructure) { + if !g.IsContainer(field.Type.ExternalStructure) { sb.WriteString(fmt.Sprintf(" + %d\n", tagSize)) } else { sb.WriteString("\n") @@ -292,7 +438,7 @@ func (g *GoGen) GenSize() string { func (g *GoGen) GenSizePlain() string { var sb strings.Builder - ctr := g.ctrStmt + ctr := g.containerStmt g.plainGen = true defer func() { g.plainGen = false }() @@ -309,7 +455,7 @@ func (g *GoGen) GenSizePlain() string { } func (g *GoGen) getMarshalFunc() string { - ctr := g.ctrStmt + ctr := g.containerStmt field := g.field switch { @@ -319,8 +465,8 @@ func (g *GoGen) getMarshalFunc() string { case field.Type.IsMap: return fmt.Sprintf("bstd.MarshalMap(n, b, %s.%s, %s, %s)", ctr.PrivateName, field.PublicName, g.getElemMarshalFunc(field.Type.MapKeyType), g.getElemMarshalFunc(field.Type.ChildType)) - case field.Type.ExtStructure != "": - if g.IsEnum(field.Type.ExtStructure) { + case field.Type.IsAnExternalStructure(): + if g.IsEnum(field.Type.ExternalStructure) { return fmt.Sprintf("bgenimpl.MarshalEnum(n, b, %s.%s)", ctr.PrivateName, field.PublicName) } @@ -329,8 +475,8 @@ func (g *GoGen) getMarshalFunc() string { return fmt.Sprintf("%s.%s.MarshalPlain(n, b)", ctr.PrivateName, field.PublicName) } - return fmt.Sprintf("%s.%s.marshal(n, b, %d)", - ctr.PrivateName, field.PublicName, field.Id) + return fmt.Sprintf("%s.%s.NestedMarshal(n, b, %d)", + ctr.PrivateName, field.PublicName, field.ID) default: return fmt.Sprintf("bstd.Marshal%s%s(n, b, %s.%s)", field.AppendUnsafeIfPresent(), field.Type.TokenType.String(), ctr.PrivateName, field.PublicName) @@ -345,13 +491,13 @@ func (g *GoGen) getElemMarshalFunc(t *parser.Type) string { case t.IsMap: return fmt.Sprintf("func (n int, b []byte, s %s) int { return bstd.MarshalMap(n, b, s, %s, %s) }", utils.BencTypeToGolang(t), g.getElemMarshalFunc(t.MapKeyType), g.getElemMarshalFunc(t.ChildType)) - case t.ExtStructure != "": - if g.IsEnum(t.ExtStructure) { + case t.IsAnExternalStructure(): + if g.IsEnum(t.ExternalStructure) { return "bgenimpl.MarshalEnum" } return fmt.Sprintf("func (n int, b []byte, s %s) int { return s.MarshalPlain(n, b) }", - utils.ToUpper(t.ExtStructure)) + utils.ToUpper(t.ExternalStructure)) default: return "bstd.Marshal" + t.AppendUnsafeIfPresent() + t.TokenType.String() } @@ -359,20 +505,20 @@ func (g *GoGen) getElemMarshalFunc(t *parser.Type) string { func (g *GoGen) GenMarshal() string { var sb strings.Builder - ctr := g.ctrStmt + ctr := g.containerStmt - sb.WriteString(fmt.Sprintf("// Marshal - %s\nfunc (%s *%s) Marshal(b []byte) {\n %s.marshal(0, b, 0)\n}\n\n", + sb.WriteString(fmt.Sprintf("// Marshal - %s\nfunc (%s *%s) Marshal(b []byte) {\n %s.NestedMarshal(0, b, 0)\n}\n\n", ctr.DefaultName, ctr.PrivateName, ctr.PublicName, ctr.PrivateName)) - sb.WriteString(fmt.Sprintf("// Nested Marshal - %s\nfunc (%s *%s) marshal(tn int, b []byte, id uint16) (n int) {\n n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id)\n", + sb.WriteString(fmt.Sprintf("// Nested Marshal - %s\nfunc (%s *%s) NestedMarshal(tn int, b []byte, id uint16) (n int) {\n n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id)\n", ctr.DefaultName, ctr.PrivateName, ctr.PublicName)) g.ForEachCtrFields(func(_ int) { field := g.field - if !g.IsCtr(field.Type.ExtStructure) { + if !g.IsContainer(field.Type.ExternalStructure) { sb.WriteString(fmt.Sprintf(" n = bgenimpl.MarshalTag(n, b, bgenimpl.%s, %d)\n", - g.mapTokenTypeToBgenimplType(field.Type.TokenType), field.Id)) + g.mapTokenTypeToBgenimplType(field.Type.TokenType), field.ID)) } sb.WriteString(fmt.Sprintf(" n = %s\n", g.getMarshalFunc())) }) @@ -383,7 +529,7 @@ func (g *GoGen) GenMarshal() string { func (g *GoGen) GenMarshalPlain() string { var sb strings.Builder - ctr := g.ctrStmt + ctr := g.containerStmt g.plainGen = true defer func() { g.plainGen = false }() @@ -419,7 +565,7 @@ func (g *GoGen) mapTokenTypeToBgenimplType(t lexer.Token) string { } func (g *GoGen) getUnmarshalFunc() string { - ctr := g.ctrStmt + ctr := g.containerStmt field := g.field switch { @@ -429,9 +575,9 @@ func (g *GoGen) getUnmarshalFunc() string { case field.Type.IsMap: return fmt.Sprintf("bstd.UnmarshalMap[%s, %s](n, b, %s, %s)", utils.BencTypeToGolang(field.Type.MapKeyType), utils.BencTypeToGolang(field.Type.ChildType), g.getElemUnmarshalFunc(field.Type.MapKeyType), g.getElemUnmarshalFunc(field.Type.ChildType)) - case field.Type.ExtStructure != "": - if g.IsEnum(field.Type.ExtStructure) { - return fmt.Sprintf("bgenimpl.UnmarshalEnum[%s](n, b)", field.Type.ExtStructure) + case field.Type.IsAnExternalStructure(): + if g.IsEnum(field.Type.ExternalStructure) { + return fmt.Sprintf("bgenimpl.UnmarshalEnum[%s](n, b)", field.Type.ExternalStructure) } if g.plainGen { return fmt.Sprintf("%s.%s.UnmarshalPlain(n, b)", ctr.PrivateName, field.PublicName) @@ -450,12 +596,12 @@ func (g *GoGen) getElemUnmarshalFunc(t *parser.Type) string { case t.IsMap: return fmt.Sprintf("func (n int, b []byte) (int, %s, error) { return bstd.UnmarshalMap[%s, %s](n, b, %s, %s) }", utils.BencTypeToGolang(t), utils.BencTypeToGolang(t.MapKeyType), utils.BencTypeToGolang(t.ChildType), g.getElemUnmarshalFunc(t.MapKeyType), g.getElemUnmarshalFunc(t.ChildType)) - case t.ExtStructure != "": - if g.IsEnum(t.ExtStructure) { + case t.IsAnExternalStructure(): + if g.IsEnum(t.ExternalStructure) { return "bgenimpl.UnmarshalEnum" } return fmt.Sprintf("func (n int, b []byte, s *%s) (int, error) { return s.UnmarshalPlain(n, b) }", - utils.ToUpper(t.ExtStructure)) + utils.ToUpper(t.ExternalStructure)) default: return "bstd.Unmarshal" + t.AppendUnsafeIfPresent() + t.TokenType.String() } @@ -463,25 +609,25 @@ func (g *GoGen) getElemUnmarshalFunc(t *parser.Type) string { func (g *GoGen) GenUnmarshal() string { var sb strings.Builder - ctr := g.ctrStmt + ctr := g.containerStmt - sb.WriteString(fmt.Sprintf("// Unmarshal - %s\nfunc (%s *%s) Unmarshal(b []byte) (err error) {\n _, err = %s.unmarshal(0, b, []uint16{}, 0)\n return\n}\n\n", + sb.WriteString(fmt.Sprintf("// Unmarshal - %s\nfunc (%s *%s) Unmarshal(b []byte) (err error) {\n _, err = %s.NestedUnmarshal(0, b, []uint16{}, 0)\n return\n}\n\n", ctr.DefaultName, ctr.PrivateName, ctr.PublicName, ctr.PrivateName)) - sb.WriteString(fmt.Sprintf("// Nested Unmarshal - %s\nfunc (%s *%s) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) {\n var ok bool\n if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok {\n if err == bgenimpl.ErrEof {\n return n, nil\n }\n return\n }\n", + sb.WriteString(fmt.Sprintf("// Nested Unmarshal - %s\nfunc (%s *%s) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) {\n var ok bool\n if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok {\n if err == bgenimpl.ErrEof {\n return n, nil\n }\n return\n }\n", ctr.DefaultName, ctr.PrivateName, ctr.PublicName)) g.ForEachCtrFields(func(_ int) { field := g.field - if g.IsCtr(field.Type.ExtStructure) { - sb.WriteString(fmt.Sprintf(" if n, err = %s.%s.unmarshal(n, b, %sRIds, %d); err != nil {\n return\n }\n", - ctr.PrivateName, field.PublicName, ctr.PrivateName, field.Id)) + if g.IsContainer(field.Type.ExternalStructure) { + sb.WriteString(fmt.Sprintf(" if n, err = %s.%s.NestedUnmarshal(n, b, %sRIds, %d); err != nil {\n return\n }\n", + ctr.PrivateName, field.PublicName, ctr.PrivateName, field.ID)) return } sb.WriteString(fmt.Sprintf(" if n, ok, err = bgenimpl.HandleCompatibility(n, b, %sRIds, %d); err != nil {\n if err == bgenimpl.ErrEof {\n return n, nil\n }\n return\n }\n", - ctr.PrivateName, field.Id)) + ctr.PrivateName, field.ID)) sb.WriteString(fmt.Sprintf(" if ok {\n if n, %s.%s, err = %s; err != nil {\n return\n }\n }\n", ctr.PrivateName, field.PublicName, g.getUnmarshalFunc())) @@ -493,7 +639,7 @@ func (g *GoGen) GenUnmarshal() string { func (g *GoGen) GenUnmarshalPlain() string { var sb strings.Builder - ctr := g.ctrStmt + ctr := g.containerStmt g.plainGen = true defer func() { g.plainGen = false }() @@ -504,7 +650,7 @@ func (g *GoGen) GenUnmarshalPlain() string { g.ForEachCtrFields(func(_ int) { field := g.field - if g.IsCtr(field.Type.ExtStructure) { + if g.IsContainer(field.Type.ExternalStructure) { sb.WriteString(fmt.Sprintf(" if n, err = %s; err != nil {\n return\n }\n", g.getUnmarshalFunc())) return diff --git a/cmd/bencgen/lexer/lexer.go b/cmd/bencgen/lexer/lexer.go index 434dee5..fdc80a6 100644 --- a/cmd/bencgen/lexer/lexer.go +++ b/cmd/bencgen/lexer/lexer.go @@ -2,7 +2,9 @@ package lexer import ( "bufio" + "fmt" "io" + "os" "strings" "unicode" ) @@ -15,9 +17,15 @@ const ( NUMBER IDENT - HEADER // header ... + USE // use ... + VAR // var ... + CTR // container ... + ENUM // enum ... + DEFINE // define ... RESERVED // reserved ... + STR_VALUE // "..." + // types INT64 INT32 @@ -39,7 +47,7 @@ const ( BYTE // types - UNSAFE // @unsafe + UNSAFE // unsafe // type attributes OPEN_BRACKET // [ @@ -50,22 +58,23 @@ const ( OPEN_ARROW // < CLOSE_ARROW // > - ENUM // enum - CTR // container COMMA // , EQUALS // = SEMICOLON // ; ) var tokens = []string{ - EOF: "EOF", - ILLEGAL: "Illegal", - NUMBER: "Number", - HEADER: "Header", - RESERVED: "Reserved", - IDENT: "Identifier", - CTR: "Container", - ENUM: "Enum", + EOF: "EOF", + ILLEGAL: "Illegal", + NUMBER: "Number", + DEFINE: "Define", + RESERVED: "Reserved", + VAR: "Var", + USE: "Use", + IDENT: "Identifier", + STR_VALUE: "String Value", + CTR: "Container", + ENUM: "Enum", INT64: "Int64", INT32: "Int32", @@ -103,9 +112,11 @@ var tokens = []string{ var keywords = map[string]Token{ "reserved": RESERVED, - "header": HEADER, - "ctr": CTR, + "define": DEFINE, + "var": VAR, "enum": ENUM, + "use": USE, + "ctr": CTR, "int64": INT64, "int32": INT32, @@ -126,7 +137,7 @@ var keywords = map[string]Token{ "bytes": BYTES, "string": STRING, - "@unsafe": UNSAFE, + "unsafe": UNSAFE, } func (t Token) String() string { @@ -186,6 +197,30 @@ func NewLexer(reader io.Reader, content string) *Lexer { } } +func (l *Lexer) error(message string) { + errorMessage := "\n\033[1;31m[bencgen] Error:\033[0m\n" + errorMessage += fmt.Sprintf(" \033[1;37m%d:%d\033[0m %s\n", l.pos.Line, l.pos.Column, highlightError(l.Content, l.pos.Line, l.pos.Column)) + errorMessage += fmt.Sprintf(" \033[1;37mMessage:\033[0m %s\n", message) + fmt.Println(errorMessage) + os.Exit(-1) +} + +func highlightError(text string, lineNumber, columnNumber int) string { + lines := strings.Split(text, "\n") + if lineNumber <= 0 || lineNumber > len(lines) { + return "Invalid line number <- report" + } + + line := lines[lineNumber-1] + if columnNumber <= 0 || columnNumber > len(line) { + return "Invalid column number <- report" + } + + highlightedLine := fmt.Sprintf("%s\033[1;31m%c\033[0m%s", line[:columnNumber], line[columnNumber], line[columnNumber+1:]) + arrow := strings.Repeat(" ", columnNumber-1+6+len(fmt.Sprintf("%d:%d", lineNumber, columnNumber))) + "\033[1;31m^\033[0m" + return highlightedLine + "\n" + arrow +} + func (l *Lexer) Lex() (Position, Token, string) { comment := false @@ -233,6 +268,20 @@ func (l *Lexer) Lex() (Position, Token, string) { return l.pos, EQUALS, "=" case ';': return l.pos, SEMICOLON, ";" + case '"': + var sb strings.Builder + for { + r, _, err := l.reader.ReadRune() + if r == '\n' { + l.error("String isn't valid (no end, expected: \"...\").") + } + if err != nil || r == '"' { + break + } + l.pos.Column++ + sb.WriteRune(r) + } + return l.pos, STR_VALUE, sb.String() default: if unicode.IsSpace(r) { continue @@ -255,15 +304,6 @@ func (l *Lexer) Lex() (Position, Token, string) { return startPos, IDENT, lit } - if r == '@' { - startPos := l.pos - lit := l.lexAtPrefixedIdent() - if token, ok := keywords[lit]; ok { - return startPos, token, lit - } - return startPos, ILLEGAL, lit - } - return l.pos, ILLEGAL, string(r) } } @@ -299,22 +339,7 @@ func (l *Lexer) lexIdent() string { var sb strings.Builder for { r, _, err := l.reader.ReadRune() - if err != nil || !(unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_') { - l.backup() - break - } - l.pos.Column++ - sb.WriteRune(r) - } - return sb.String() -} - -func (l *Lexer) lexAtPrefixedIdent() string { - var sb strings.Builder - sb.WriteRune('@') - for { - r, _, err := l.reader.ReadRune() - if err != nil || !(unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_') { + if err != nil || !(unicode.IsLetter(r) || unicode.IsDigit(r) || r == '.' || r == '_') { l.backup() break } diff --git a/cmd/bencgen/main.go b/cmd/bencgen/main.go index 3437add..0a75418 100644 --- a/cmd/bencgen/main.go +++ b/cmd/bencgen/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "os" + "path/filepath" "strings" "time" @@ -12,11 +13,12 @@ import ( "github.com/deneonet/benc/cmd/bencgen/parser" ) -var iFlag = flag.String("in", "", "the input .benc file") +var iFlag = flag.String("in", "", "comma-separated list of input .benc files") var oFlag = flag.String("out", "", "the output directory") -var nFlag = flag.String("file", "", "the name of the output file (no extension)") +var nFlag = flag.String("file", "", "custom output filename (use '...' to replace with input filename)") var fFlag = flag.Bool("force", false, "disables the breaking-change detector") var lFlag = flag.String("lang", "", "the language of the code that should be generated") +var dFlag = flag.String("import-dir", "", "comma-separated list of import directories") func printError(m string) { errorMessage := "\n\033[1;31m[bencgen] Error:\033[0m\n" @@ -25,79 +27,85 @@ func printError(m string) { os.Exit(-1) } -func main() { - flag.Usage = func() { - fmt.Println("Usage for bencgen available here: https://github.com/deneonet/benc/cmd/bencgen#usage") - } - flag.Parse() - - if len(*iFlag) == 0 { - printError("Missing input file: --in ...") - return - } - - if len(*lFlag) == 0 { - printError("Missing language: --lang ...") - return - } - - lang := codegens.GenLang(*lFlag) - generator := codegens.NewGen(lang, *iFlag) +func processFile(inputFile string, outputDir string, filenamePattern string, lang codegens.GenLang, importDirs []string) { + generator := codegens.NewGen(lang, inputFile) if generator == nil { printError("Unknown language provided.") - return } start := time.Now() - file, err := os.Open(*iFlag) + content, err := os.ReadFile(inputFile) if err != nil { panic(err) } - content, err := os.ReadFile(*iFlag) - if err != nil { + parser := parser.NewParser(strings.NewReader(string(content)), string(content)) + nodes := parser.Parse() + + outCode := codegens.Generate(generator, nodes, importDirs) + + bcd := bcd.NewBcd(nodes, inputFile) + bcd.Analyze(*fFlag) + + fileBase := strings.TrimSuffix(filepath.Base(inputFile), ".benc") + outputFilename := strings.ReplaceAll(filenamePattern, "...", fileBase) + "." + *lFlag + + outputDir = strings.ReplaceAll(outputDir, "...", fileBase) + + if err := os.MkdirAll(outputDir, os.ModePerm); err != nil { panic(err) } - parser := parser.NewParser(file, string(content)) - nodes := parser.Parse() + outputPath := filepath.Join(outputDir, outputFilename) + if err := os.WriteFile(outputPath, []byte(outCode), os.ModePerm); err != nil { + panic(err) + } - bcd := bcd.NewBcd(nodes, *iFlag) - bcd.Analyze(*fFlag) + elapsed := time.Since(start) - outCode := codegens.Generate(generator, nodes) + successMessage := "\n\033[1;92m[bencgen] Success:\033[0m\n" + successMessage += fmt.Sprintf(" \033[37mCompiled %s into `%s`, in %dms, saved at: %s !\033[0m\n", inputFile, *lFlag, elapsed.Milliseconds(), outputPath) + fmt.Println(successMessage) +} - dn := "out" - if len(*oFlag) != 0 { - dn = *oFlag +func main() { + flag.Usage = func() { + fmt.Println("Usage for bencgen available here: https://github.com/deneonet/benc/tree/main/cmd/bencgen#usage") } + flag.Parse() - fn := *iFlag - if len(*nFlag) != 0 { - fn = *nFlag + if len(*iFlag) == 0 { + printError("Missing input file(s): --in ...") } - if strings.Contains(fn, "/") { - out := strings.Split(fn, "/") - fn = out[len(out)-1] + if len(*lFlag) == 0 { + printError("Missing language: --lang ...") } - ffn := fn + "." + *lFlag + var importDirs []string + if len(*dFlag) > 0 { + importDirs = strings.Split(*dFlag, ",") + } - err = os.MkdirAll(dn, os.ModePerm) - if err != nil { - panic(err) + lang := codegens.GenLang(*lFlag) + outputDir := "out" + if len(*oFlag) != 0 { + outputDir = *oFlag } - err = os.WriteFile(dn+"/"+ffn, []byte(outCode), os.ModePerm) - if err != nil { - panic(err) + filenamePattern := "..." + if len(*nFlag) != 0 { + filenamePattern = *nFlag } - elapsed := time.Since(start) + inputFiles := strings.Split(*iFlag, ",") - successMessage := "\n\033[1;92m[bencgen] Success:\033[0m\n" - successMessage += fmt.Sprintf(" \033[37mCompiled into `%s`, in %dms, saved at: %s !\033[0m\n", *lFlag, elapsed.Milliseconds(), dn+"/"+ffn) - fmt.Println(successMessage) + for _, inputFile := range inputFiles { + inputFile = strings.TrimSpace(inputFile) + if inputFile == "" { + continue + } + processFile(inputFile, outputDir, filenamePattern, lang, importDirs) + } } diff --git a/cmd/bencgen/parser/parser.go b/cmd/bencgen/parser/parser.go index 205fe77..09ed110 100644 --- a/cmd/bencgen/parser/parser.go +++ b/cmd/bencgen/parser/parser.go @@ -17,9 +17,9 @@ type Parser struct { pos lexer.Position } -func NewParser(reader io.Reader, fc string) *Parser { +func NewParser(reader io.Reader, fileContent string) *Parser { return &Parser{ - lexer: lexer.NewLexer(reader, fc), + lexer: lexer.NewLexer(reader, fileContent), } } @@ -34,7 +34,7 @@ func (p *Parser) match(expected lexer.Token) bool { return p.token == expected } -func (p *Parser) mMatch(expected ...lexer.Token) bool { +func (p *Parser) matchAny(expected ...lexer.Token) bool { for _, token := range expected { if p.token == token { return true @@ -50,113 +50,6 @@ func (p *Parser) expect(expected lexer.Token) { p.nextToken() } -func (p *Parser) expectType() *Type { - switch { - case p.match(lexer.OPEN_BRACKET): - p.nextToken() - p.expect(lexer.CLOSE_BRACKET) - return &Type{IsArray: true, ChildType: p.expectType()} - - case p.match(lexer.OPEN_ARROW): - p.nextToken() - key := p.expectType() - p.expect(lexer.COMMA) - val := p.expectType() - p.expect(lexer.CLOSE_ARROW) - return &Type{IsMap: true, MapKeyType: key, ChildType: val} - - case p.match(lexer.IDENT): - ctrName := p.lit - p.nextToken() - return &Type{ExtStructure: ctrName} - - case p.match(lexer.UNSAFE): - p.nextToken() - typ := p.token - p.nextToken() - if typ != lexer.STRING { - p.error("`@unsafe` can only be applied to `string` types") - } - return &Type{IsUnsafe: true, TokenType: typ} - - default: - if p.mMatch(lexer.STRING, lexer.BYTES, lexer.INT, lexer.INT16, lexer.INT32, lexer.INT64, lexer.UINT, lexer.UINT16, lexer.UINT32, lexer.UINT64, lexer.FLOAT32, lexer.FLOAT64, lexer.BYTE, lexer.BOOL) { - typ := p.token - p.nextToken() - return &Type{TokenType: typ} - } - p.error("Unexpected token, expected a type") - return nil - } -} - -func highlightError(text string, lineNumber, columnNumber int) string { - lines := strings.Split(text, "\n") - - if lineNumber <= 0 || lineNumber > len(lines) { - return "Invalid line number <- report" - } - - line := lines[lineNumber-1] - if columnNumber <= 0 || columnNumber > len(line) { - return "Invalid column number <- report" - } - - highlightedLine := fmt.Sprintf("%s\033[1;31m%c\033[0m%s", line[:columnNumber], line[columnNumber], line[columnNumber+1:]) - arrow := strings.Repeat(" ", columnNumber-1+6+len(fmt.Sprintf("%d:%d", lineNumber, columnNumber))) + "\033[1;31m^\033[0m" - return highlightedLine + "\n" + arrow -} - -func (p *Parser) error(m string) { - errorMessage := "\n\033[1;31m[bencgen] Error:\033[0m\n" - errorMessage += fmt.Sprintf(" \033[1;37m%d:%d\033[0m %s\n", p.pos.Line, p.pos.Column, highlightError(p.lexer.Content, p.pos.Line, p.pos.Column)) - errorMessage += fmt.Sprintf(" \033[1;37mMessage:\033[0m %s\n", m) - fmt.Println(errorMessage) - os.Exit(-1) -} - -type Node interface{} - -type ( - Type struct { - TokenType lexer.Token - MapKeyType *Type - ChildType *Type - ExtStructure string `json:"ctrName"` - IsUnsafe bool - IsArray bool - IsMap bool - } - HeaderStmt struct { - Name string - } - CtrStmt struct { - Name string - Fields []Field - ReservedIds []uint16 - } - EnumStmt struct { - Name string - Fields []string - } - Field struct { - Id uint16 - Name string - Type *Type - } -) - -func (t *Type) AppendUnsafeIfPresent() string { - if !t.IsUnsafe { - return "" - } - return "Unsafe" -} - -func (f *Field) AppendUnsafeIfPresent() string { - return f.Type.AppendUnsafeIfPresent() -} - func (p *Parser) Parse() []Node { var nodes []Node p.nextToken() @@ -168,77 +61,108 @@ func (p *Parser) Parse() []Node { func (p *Parser) parseStatement() Node { switch { - case p.match(lexer.HEADER): - return p.parseHeaderStmt() case p.match(lexer.CTR): - return p.parseCtrStmt() + return p.parseContainerStmt() case p.match(lexer.ENUM): return p.parseEnumStmt() + case p.match(lexer.DEFINE): + return p.parseDefineStmt() + case p.match(lexer.VAR): + return p.parseVarStmt() + case p.match(lexer.USE): + return p.parseUseStmt() default: - p.error(fmt.Sprintf("Unexpected token: `%s`. Expected: `Container, Enum or Header`", p.token)) + p.error(fmt.Sprintf("Unexpected token: `%s`. Expected: `Container, Enum, Define, Use or Var`", p.token)) return nil } } -func (p *Parser) parseHeaderStmt() Node { - p.expect(lexer.HEADER) - headerName := p.lit - p.expect(lexer.IDENT) - p.expect(lexer.SEMICOLON) - return &HeaderStmt{Name: headerName} -} - -func (p *Parser) parseCtrStmt() Node { +func (p *Parser) parseContainerStmt() Node { p.expect(lexer.CTR) - name := p.lit + containerName := p.lit p.expect(lexer.IDENT) + p.errorIfContainsDot(containerName, "Container names") + p.expect(lexer.OPEN_BRACE) - reservedIds := p.parseReservedIds() + reservedIDs := p.parseReservedIDs() fields := p.parseFields() p.expect(lexer.CLOSE_BRACE) - return &CtrStmt{Name: name, ReservedIds: reservedIds, Fields: fields} + return &ContainerStmt{Name: containerName, ReservedIDs: reservedIDs, Fields: fields} } func (p *Parser) parseEnumStmt() Node { p.expect(lexer.ENUM) - name := p.lit + enumName := p.lit p.expect(lexer.IDENT) + p.errorIfContainsDot(enumName, "Enum names") + p.expect(lexer.OPEN_BRACE) - fields := p.parseEnumFields() + values := p.parseEnumValues() p.expect(lexer.CLOSE_BRACE) - return &EnumStmt{Name: name, Fields: fields} + return &EnumStmt{Name: enumName, Values: values} +} + +func (p *Parser) parseDefineStmt() Node { + p.expect(lexer.DEFINE) + definePackage := p.lit + p.expect(lexer.IDENT) + p.expect(lexer.SEMICOLON) + return &DefineStmt{Package: definePackage} +} + +func (p *Parser) parseVarStmt() Node { + p.expect(lexer.VAR) + name := p.lit + p.expect(lexer.IDENT) + p.errorIfContainsDot(name, "Var names") + + p.expect(lexer.EQUALS) + value := p.lit + p.expect(lexer.STR_VALUE) + p.expect(lexer.SEMICOLON) + return &VarStmt{Name: name, Value: value} +} + +func (p *Parser) parseUseStmt() Node { + p.expect(lexer.USE) + path := p.lit + p.expect(lexer.STR_VALUE) + p.expect(lexer.SEMICOLON) + return &UseStmt{Path: path} } -func (p *Parser) parseEnumFields() []string { - var fields []string +func (p *Parser) parseEnumValues() []string { + var values []string for !p.match(lexer.CLOSE_BRACE) { - fields = append(fields, p.parseEnumField()) + values = append(values, p.parseEnumValue()) } - return fields + return values } -func (p *Parser) parseEnumField() string { - ident := p.lit +func (p *Parser) parseEnumValue() string { + value := p.lit p.expect(lexer.IDENT) + p.errorIfContainsDot(value, "Enum value names") + if !p.match(lexer.CLOSE_BRACE) { p.expect(lexer.COMMA) } - return ident + return value } -func (p *Parser) parseReservedIds() []uint16 { +func (p *Parser) parseReservedIDs() []uint16 { if p.match(lexer.RESERVED) { p.nextToken() - return p.parseIdList() + return p.parseIDList() } return nil } -func (p *Parser) parseIdList() []uint16 { +func (p *Parser) parseIDList() []uint16 { var ids []uint16 for { id, err := strconv.ParseUint(p.lit, 10, 16) @@ -266,10 +190,12 @@ func (p *Parser) parseFields() []Field { } func (p *Parser) parseField() Field { - t := p.expectType() + fieldType := p.expectType() - n := p.lit + fieldName := p.lit p.expect(lexer.IDENT) + p.errorIfContainsDot(fieldName, "Container field names") + p.expect(lexer.EQUALS) id, err := strconv.ParseUint(p.lit, 10, 16) @@ -279,5 +205,124 @@ func (p *Parser) parseField() Field { } p.expect(lexer.SEMICOLON) - return Field{Id: uint16(id), Name: n, Type: t} + return Field{ID: uint16(id), Name: fieldName, Type: fieldType} +} + +func (p *Parser) expectType() *Type { + switch { + case p.match(lexer.OPEN_BRACKET): + p.nextToken() + p.expect(lexer.CLOSE_BRACKET) + return &Type{IsArray: true, ChildType: p.expectType()} + + case p.match(lexer.OPEN_ARROW): + p.nextToken() + keyType := p.expectType() + p.expect(lexer.COMMA) + valueType := p.expectType() + p.expect(lexer.CLOSE_ARROW) + return &Type{IsMap: true, MapKeyType: keyType, ChildType: valueType} + + case p.match(lexer.IDENT): + ctrName := p.lit + p.nextToken() + return &Type{ExternalStructure: ctrName} + + case p.match(lexer.UNSAFE): + p.nextToken() + tokenType := p.token + p.nextToken() + if tokenType != lexer.STRING { + p.error("`unsafe` can only be applied to `string` types") + } + return &Type{IsUnsafe: true, TokenType: tokenType} + + default: + if p.matchAny(lexer.STRING, lexer.BYTES, lexer.INT, lexer.INT16, lexer.INT32, lexer.INT64, lexer.UINT, lexer.UINT16, lexer.UINT32, lexer.UINT64, lexer.FLOAT32, lexer.FLOAT64, lexer.BYTE, lexer.BOOL) { + tokenType := p.token + p.nextToken() + return &Type{TokenType: tokenType} + } + p.error("Unexpected token, expected a type") + return nil + } +} + +func (p *Parser) error(message string) { + errorMessage := "\n\033[1;31m[bencgen] Error:\033[0m\n" + errorMessage += fmt.Sprintf(" \033[1;37m%d:%d\033[0m %s\n", p.pos.Line, p.pos.Column, highlightError(p.lexer.Content, p.pos.Line, p.pos.Column)) + errorMessage += fmt.Sprintf(" \033[1;37mMessage:\033[0m %s\n", message) + fmt.Println(errorMessage) + os.Exit(-1) +} + +func highlightError(text string, lineNumber, columnNumber int) string { + lines := strings.Split(text, "\n") + if lineNumber <= 0 || lineNumber > len(lines) { + return "Invalid line number <- report" + } + + line := lines[lineNumber-1] + if columnNumber <= 0 || columnNumber > len(line) { + return "Invalid column number <- report" + } + + highlightedLine := fmt.Sprintf("%s\033[1;31m%c\033[0m%s", line[:columnNumber], line[columnNumber], line[columnNumber+1:]) + arrow := strings.Repeat(" ", columnNumber-1+6+len(fmt.Sprintf("%d:%d", lineNumber, columnNumber))) + "\033[1;31m^\033[0m" + return highlightedLine + "\n" + arrow +} + +func (p *Parser) errorIfContainsDot(ident string, context string) { + if strings.Contains(ident, ".") { + p.error(context + " may not contain a dot '.'") + } +} + +type Node interface{} + +type ( + Type struct { + TokenType lexer.Token + MapKeyType *Type + ChildType *Type + ExternalStructure string `json:"ctrName"` + IsUnsafe bool + IsArray bool + IsMap bool + } + ContainerStmt struct { + Name string + Fields []Field + ReservedIDs []uint16 + } + EnumStmt struct { + Name string + Values []string + } + DefineStmt struct { + Package string + } + VarStmt struct { + Name string + Value string + } + UseStmt struct { + Path string + } + Field struct { + ID uint16 `json:"id"` + Name string + Type *Type + } +) + +func (t *Type) IsAnExternalStructure() bool { + return t.ExternalStructure != "" +} + +func (t *Type) AppendUnsafeIfPresent() string { + if t.IsUnsafe { + return "Unsafe" + } + return "" } diff --git a/cmd/bencgen/utils/utils.go b/cmd/bencgen/utils/utils.go index f4b9e84..9e89dae 100644 --- a/cmd/bencgen/utils/utils.go +++ b/cmd/bencgen/utils/utils.go @@ -36,8 +36,8 @@ func formatTypeHelper(t *parser.Type, useGoFormat bool) string { return "<" + keyFormat + ", " + valueFormat + ">" } - if t.ExtStructure != "" { - return t.ExtStructure + if t.IsAnExternalStructure() { + return t.ExternalStructure } if useGoFormat { @@ -51,8 +51,8 @@ func CompareTypes(t1 *parser.Type, t2 *parser.Type) bool { } func FindUndeclaredContainersOrEnums(declarations []string, t *parser.Type) (string, bool) { - if t.ExtStructure != "" && !slices.Contains(declarations, t.ExtStructure) { - return t.ExtStructure, true + if t.IsAnExternalStructure() && !slices.Contains(declarations, t.ExternalStructure) { + return t.ExternalStructure, true } if t.ChildType != nil { @@ -78,7 +78,7 @@ func compareTypes(t1 *parser.Type, t2 *parser.Type) bool { return t1.IsArray == t2.IsArray && t1.IsMap == t2.IsMap && t1.TokenType == t2.TokenType && - t1.ExtStructure == t2.ExtStructure && + t1.ExternalStructure == t2.ExternalStructure && compareTypes(t1.MapKeyType, t2.MapKeyType) && compareTypes(t1.ChildType, t2.ChildType) } diff --git a/codecov.yml b/codecov.yml index c4f4f9e..3b3404f 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,2 +1,3 @@ ignore: - - "cmd" \ No newline at end of file + - "cmd" + - "testing" diff --git a/testing/complex_data/complex_data.go b/testing/complex_data/complex_data.go new file mode 100644 index 0000000..6511c4d --- /dev/null +++ b/testing/complex_data/complex_data.go @@ -0,0 +1,639 @@ +// Code generated by bencgen go. DO NOT EDIT. +// source: ../schemas/complex_data.benc + +package complex_data + +import ( + "github.com/deneonet/benc/std" + "github.com/deneonet/benc/impl/gen" + + +) + +// Struct - ComplexData +type ComplexData struct { + Id int + Title string + Items []SubItem + Metadata map[string]int32 + Sub_data SubComplexData + Large_binary_data [][]byte + Huge_list []int64 +} + +// Reserved Ids - ComplexData +var complexDataRIds = []uint16{} + +// Size - ComplexData +func (complexData *ComplexData) Size() int { + return complexData.NestedSize(0) +} + +// Nested Size - ComplexData +func (complexData *ComplexData) NestedSize(id uint16) (s int) { + s += bstd.SizeInt(complexData.Id) + 2 + s += bstd.SizeString(complexData.Title) + 2 + s += bstd.SizeSlice(complexData.Items, func (s SubItem) int { return s.SizePlain() }) + 2 + s += bstd.SizeMap(complexData.Metadata, bstd.SizeString, bstd.SizeInt32) + 2 + s += complexData.Sub_data.NestedSize(5) + s += bstd.SizeSlice(complexData.Large_binary_data, bstd.SizeBytes) + 2 + s += bstd.SizeSlice(complexData.Huge_list, bstd.SizeInt64) + 2 + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - ComplexData +func (complexData *ComplexData) SizePlain() (s int) { + s += bstd.SizeInt(complexData.Id) + s += bstd.SizeString(complexData.Title) + s += bstd.SizeSlice(complexData.Items, func (s SubItem) int { return s.SizePlain() }) + s += bstd.SizeMap(complexData.Metadata, bstd.SizeString, bstd.SizeInt32) + s += complexData.Sub_data.SizePlain() + s += bstd.SizeSlice(complexData.Large_binary_data, bstd.SizeBytes) + s += bstd.SizeSlice(complexData.Huge_list, bstd.SizeInt64) + return +} + +// Marshal - ComplexData +func (complexData *ComplexData) Marshal(b []byte) { + complexData.NestedMarshal(0, b, 0) +} + +// Nested Marshal - ComplexData +func (complexData *ComplexData) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Varint, 1) + n = bstd.MarshalInt(n, b, complexData.Id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) + n = bstd.MarshalString(n, b, complexData.Title) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) + n = bstd.MarshalSlice(n, b, complexData.Items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 4) + n = bstd.MarshalMap(n, b, complexData.Metadata, bstd.MarshalString, bstd.MarshalInt32) + n = complexData.Sub_data.NestedMarshal(n, b, 5) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 6) + n = bstd.MarshalSlice(n, b, complexData.Large_binary_data, bstd.MarshalBytes) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 7) + n = bstd.MarshalSlice(n, b, complexData.Huge_list, bstd.MarshalInt64) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - ComplexData +func (complexData *ComplexData) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalInt(n, b, complexData.Id) + n = bstd.MarshalString(n, b, complexData.Title) + n = bstd.MarshalSlice(n, b, complexData.Items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) + n = bstd.MarshalMap(n, b, complexData.Metadata, bstd.MarshalString, bstd.MarshalInt32) + n = complexData.Sub_data.MarshalPlain(n, b) + n = bstd.MarshalSlice(n, b, complexData.Large_binary_data, bstd.MarshalBytes) + n = bstd.MarshalSlice(n, b, complexData.Huge_list, bstd.MarshalInt64) + return n +} + +// Unmarshal - ComplexData +func (complexData *ComplexData) Unmarshal(b []byte) (err error) { + _, err = complexData.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - ComplexData +func (complexData *ComplexData) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, complexData.Id, err = bstd.UnmarshalInt(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, complexData.Title, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 3); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, complexData.Items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 4); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, complexData.Metadata, err = bstd.UnmarshalMap[string, int32](n, b, bstd.UnmarshalString, bstd.UnmarshalInt32); err != nil { + return + } + } + if n, err = complexData.Sub_data.NestedUnmarshal(n, b, complexDataRIds, 5); err != nil { + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 6); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, complexData.Large_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 7); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, complexData.Huge_list, err = bstd.UnmarshalSlice[int64](n, b, bstd.UnmarshalInt64); err != nil { + return + } + } + n += 2 + return +} + +// UnmarshalPlain - ComplexData +func (complexData *ComplexData) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, complexData.Id, err = bstd.UnmarshalInt(n, b); err != nil { + return + } + if n, complexData.Title, err = bstd.UnmarshalString(n, b); err != nil { + return + } + if n, complexData.Items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { + return + } + if n, complexData.Metadata, err = bstd.UnmarshalMap[string, int32](n, b, bstd.UnmarshalString, bstd.UnmarshalInt32); err != nil { + return + } + if n, err = complexData.Sub_data.UnmarshalPlain(n, b); err != nil { + return + } + if n, complexData.Large_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { + return + } + if n, complexData.Huge_list, err = bstd.UnmarshalSlice[int64](n, b, bstd.UnmarshalInt64); err != nil { + return + } + return +} + +// Struct - SubItem +type SubItem struct { + Sub_id int32 + Description string + Sub_items []SubSubItem +} + +// Reserved Ids - SubItem +var subItemRIds = []uint16{} + +// Size - SubItem +func (subItem *SubItem) Size() int { + return subItem.NestedSize(0) +} + +// Nested Size - SubItem +func (subItem *SubItem) NestedSize(id uint16) (s int) { + s += bstd.SizeInt32() + 2 + s += bstd.SizeString(subItem.Description) + 2 + s += bstd.SizeSlice(subItem.Sub_items, func (s SubSubItem) int { return s.SizePlain() }) + 2 + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - SubItem +func (subItem *SubItem) SizePlain() (s int) { + s += bstd.SizeInt32() + s += bstd.SizeString(subItem.Description) + s += bstd.SizeSlice(subItem.Sub_items, func (s SubSubItem) int { return s.SizePlain() }) + return +} + +// Marshal - SubItem +func (subItem *SubItem) Marshal(b []byte) { + subItem.NestedMarshal(0, b, 0) +} + +// Nested Marshal - SubItem +func (subItem *SubItem) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed32, 1) + n = bstd.MarshalInt32(n, b, subItem.Sub_id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) + n = bstd.MarshalString(n, b, subItem.Description) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) + n = bstd.MarshalSlice(n, b, subItem.Sub_items, func (n int, b []byte, s SubSubItem) int { return s.MarshalPlain(n, b) }) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - SubItem +func (subItem *SubItem) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalInt32(n, b, subItem.Sub_id) + n = bstd.MarshalString(n, b, subItem.Description) + n = bstd.MarshalSlice(n, b, subItem.Sub_items, func (n int, b []byte, s SubSubItem) int { return s.MarshalPlain(n, b) }) + return n +} + +// Unmarshal - SubItem +func (subItem *SubItem) Unmarshal(b []byte) (err error) { + _, err = subItem.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - SubItem +func (subItem *SubItem) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subItemRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subItem.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subItemRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subItem.Description, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subItemRIds, 3); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subItem.Sub_items, err = bstd.UnmarshalSlice[SubSubItem](n, b, func (n int, b []byte, s *SubSubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { + return + } + } + n += 2 + return +} + +// UnmarshalPlain - SubItem +func (subItem *SubItem) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, subItem.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { + return + } + if n, subItem.Description, err = bstd.UnmarshalString(n, b); err != nil { + return + } + if n, subItem.Sub_items, err = bstd.UnmarshalSlice[SubSubItem](n, b, func (n int, b []byte, s *SubSubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { + return + } + return +} + +// Struct - SubSubItem +type SubSubItem struct { + Sub_sub_id string + Sub_sub_data []byte +} + +// Reserved Ids - SubSubItem +var subSubItemRIds = []uint16{} + +// Size - SubSubItem +func (subSubItem *SubSubItem) Size() int { + return subSubItem.NestedSize(0) +} + +// Nested Size - SubSubItem +func (subSubItem *SubSubItem) NestedSize(id uint16) (s int) { + s += bstd.SizeString(subSubItem.Sub_sub_id) + 2 + s += bstd.SizeBytes(subSubItem.Sub_sub_data) + 2 + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - SubSubItem +func (subSubItem *SubSubItem) SizePlain() (s int) { + s += bstd.SizeString(subSubItem.Sub_sub_id) + s += bstd.SizeBytes(subSubItem.Sub_sub_data) + return +} + +// Marshal - SubSubItem +func (subSubItem *SubSubItem) Marshal(b []byte) { + subSubItem.NestedMarshal(0, b, 0) +} + +// Nested Marshal - SubSubItem +func (subSubItem *SubSubItem) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 1) + n = bstd.MarshalString(n, b, subSubItem.Sub_sub_id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) + n = bstd.MarshalBytes(n, b, subSubItem.Sub_sub_data) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - SubSubItem +func (subSubItem *SubSubItem) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalString(n, b, subSubItem.Sub_sub_id) + n = bstd.MarshalBytes(n, b, subSubItem.Sub_sub_data) + return n +} + +// Unmarshal - SubSubItem +func (subSubItem *SubSubItem) Unmarshal(b []byte) (err error) { + _, err = subSubItem.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - SubSubItem +func (subSubItem *SubSubItem) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subSubItemRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subSubItem.Sub_sub_id, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subSubItemRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subSubItem.Sub_sub_data, err = bstd.UnmarshalBytes(n, b); err != nil { + return + } + } + n += 2 + return +} + +// UnmarshalPlain - SubSubItem +func (subSubItem *SubSubItem) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, subSubItem.Sub_sub_id, err = bstd.UnmarshalString(n, b); err != nil { + return + } + if n, subSubItem.Sub_sub_data, err = bstd.UnmarshalBytes(n, b); err != nil { + return + } + return +} + +// Struct - SubComplexData +type SubComplexData struct { + Sub_id int32 + Sub_title string + Sub_binary_data [][]byte + Sub_items []SubItem + Sub_metadata map[string]string +} + +// Reserved Ids - SubComplexData +var subComplexDataRIds = []uint16{} + +// Size - SubComplexData +func (subComplexData *SubComplexData) Size() int { + return subComplexData.NestedSize(0) +} + +// Nested Size - SubComplexData +func (subComplexData *SubComplexData) NestedSize(id uint16) (s int) { + s += bstd.SizeInt32() + 2 + s += bstd.SizeString(subComplexData.Sub_title) + 2 + s += bstd.SizeSlice(subComplexData.Sub_binary_data, bstd.SizeBytes) + 2 + s += bstd.SizeSlice(subComplexData.Sub_items, func (s SubItem) int { return s.SizePlain() }) + 2 + s += bstd.SizeMap(subComplexData.Sub_metadata, bstd.SizeString, bstd.SizeString) + 2 + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - SubComplexData +func (subComplexData *SubComplexData) SizePlain() (s int) { + s += bstd.SizeInt32() + s += bstd.SizeString(subComplexData.Sub_title) + s += bstd.SizeSlice(subComplexData.Sub_binary_data, bstd.SizeBytes) + s += bstd.SizeSlice(subComplexData.Sub_items, func (s SubItem) int { return s.SizePlain() }) + s += bstd.SizeMap(subComplexData.Sub_metadata, bstd.SizeString, bstd.SizeString) + return +} + +// Marshal - SubComplexData +func (subComplexData *SubComplexData) Marshal(b []byte) { + subComplexData.NestedMarshal(0, b, 0) +} + +// Nested Marshal - SubComplexData +func (subComplexData *SubComplexData) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed32, 1) + n = bstd.MarshalInt32(n, b, subComplexData.Sub_id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) + n = bstd.MarshalString(n, b, subComplexData.Sub_title) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) + n = bstd.MarshalSlice(n, b, subComplexData.Sub_binary_data, bstd.MarshalBytes) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 4) + n = bstd.MarshalSlice(n, b, subComplexData.Sub_items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 5) + n = bstd.MarshalMap(n, b, subComplexData.Sub_metadata, bstd.MarshalString, bstd.MarshalString) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - SubComplexData +func (subComplexData *SubComplexData) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalInt32(n, b, subComplexData.Sub_id) + n = bstd.MarshalString(n, b, subComplexData.Sub_title) + n = bstd.MarshalSlice(n, b, subComplexData.Sub_binary_data, bstd.MarshalBytes) + n = bstd.MarshalSlice(n, b, subComplexData.Sub_items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) + n = bstd.MarshalMap(n, b, subComplexData.Sub_metadata, bstd.MarshalString, bstd.MarshalString) + return n +} + +// Unmarshal - SubComplexData +func (subComplexData *SubComplexData) Unmarshal(b []byte) (err error) { + _, err = subComplexData.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - SubComplexData +func (subComplexData *SubComplexData) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subComplexData.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subComplexData.Sub_title, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 3); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subComplexData.Sub_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 4); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subComplexData.Sub_items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 5); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, subComplexData.Sub_metadata, err = bstd.UnmarshalMap[string, string](n, b, bstd.UnmarshalString, bstd.UnmarshalString); err != nil { + return + } + } + n += 2 + return +} + +// UnmarshalPlain - SubComplexData +func (subComplexData *SubComplexData) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, subComplexData.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { + return + } + if n, subComplexData.Sub_title, err = bstd.UnmarshalString(n, b); err != nil { + return + } + if n, subComplexData.Sub_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { + return + } + if n, subComplexData.Sub_items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { + return + } + if n, subComplexData.Sub_metadata, err = bstd.UnmarshalMap[string, string](n, b, bstd.UnmarshalString, bstd.UnmarshalString); err != nil { + return + } + return +} + diff --git a/testing/complex_data/complex_data_test.go b/testing/complex_data/complex_data_test.go index 9a17bb5..f1dd9b2 100644 --- a/testing/complex_data/complex_data_test.go +++ b/testing/complex_data/complex_data_test.go @@ -1,637 +1,138 @@ -// Code generated by bencgen golang. DO NOT EDIT. -// source: ../schemas/complex_data.benc +//go:generate bencgen --in ../schemas/complex_data.benc --out ./ --file ... --lang go package complex_data import ( - "github.com/deneonet/benc/std" - "github.com/deneonet/benc/impl/gen" + "fmt" + "reflect" + "testing" ) -// Struct - ComplexData -type ComplexData struct { - Id int - Title string - Items []SubItem - Metadata map[string]int32 - Sub_data SubComplexData - Large_binary_data [][]byte - Huge_list []int64 +func TestComplex(t *testing.T) { + data := ComplexData{ + Id: 12345, + Title: "Example Complex Data", + Items: []SubItem{ + { + Sub_id: 1, + Description: "SubItem 1", + Sub_items: []SubSubItem{ + { + Sub_sub_id: "subsub1", + Sub_sub_data: []byte{0x01, 0x02, 0x03}, + }, + }, + }, + }, + Metadata: map[string]int32{ + "key1": 10, + "key2": 20, + }, + Sub_data: SubComplexData{ + Sub_id: 999, + Sub_title: "Sub Complex Data", + Sub_binary_data: [][]byte{ + {0x11, 0x22, 0x33}, + {0x44, 0x55, 0x66}, + }, + Sub_items: []SubItem{ + { + Sub_id: 2, + Description: "SubItem 2", + Sub_items: []SubSubItem{ + { + Sub_sub_id: "subsub2", + Sub_sub_data: []byte{0xAA, 0xBB, 0xCC}, + }, + }, + }, + }, + Sub_metadata: map[string]string{ + "meta1": "value1", + "meta2": "value2", + }, + }, + Large_binary_data: [][]byte{ + {0xFF, 0xEE, 0xDD}, + }, + Huge_list: []int64{1000000, 2000000, 3000000}, + } + + s := data.Size() + b := make([]byte, s) + data.Marshal(b) + fmt.Println(b) + + var retData ComplexData + if err := retData.Unmarshal(b); err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(data, retData) { + t.Fatalf("no match\norg: %v\ndec: %v\n", data, retData) + } +} + +func BenchmarkComplex(b *testing.B) { + data := ComplexData{ + Id: 12345, + Title: "Example Complex Data", + Items: []SubItem{ + { + Sub_id: 1, + Description: "SubItem 1", + Sub_items: []SubSubItem{ + { + Sub_sub_id: "subsub1", + Sub_sub_data: []byte{0x01, 0x02, 0x03}, + }, + }, + }, + }, + Metadata: map[string]int32{ + "key1": 10, + "key2": 20, + }, + Sub_data: SubComplexData{ + Sub_id: 999, + Sub_title: "Sub Complex Data", + Sub_binary_data: [][]byte{ + {0x11, 0x22, 0x33}, + {0x44, 0x55, 0x66}, + }, + Sub_items: []SubItem{ + { + Sub_id: 2, + Description: "SubItem 2", + Sub_items: []SubSubItem{ + { + Sub_sub_id: "subsub2", + Sub_sub_data: []byte{0xAA, 0xBB, 0xCC}, + }, + }, + }, + }, + Sub_metadata: map[string]string{ + "meta1": "value1", + "meta2": "value2", + }, + }, + Large_binary_data: [][]byte{ + {0xFF, 0xEE, 0xDD}, + }, + Huge_list: []int64{1000000, 2000000, 3000000}, + } + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + s := data.Size() + buf := make([]byte, s) + data.Marshal(buf) + + var retData ComplexData + if err := retData.Unmarshal(buf); err != nil { + b.Fatal(err) + } + } } - -// Reserved Ids - ComplexData -var complexDataRIds = []uint16{} - -// Size - ComplexData -func (complexData *ComplexData) Size() int { - return complexData.size(0) -} - -// Nested Size - ComplexData -func (complexData *ComplexData) size(id uint16) (s int) { - s += bstd.SizeInt(complexData.Id) + 2 - s += bstd.SizeString(complexData.Title) + 2 - s += bstd.SizeSlice(complexData.Items, func (s SubItem) int { return s.SizePlain() }) + 2 - s += bstd.SizeMap(complexData.Metadata, bstd.SizeString, bstd.SizeInt32) + 2 - s += complexData.Sub_data.size(5) - s += bstd.SizeSlice(complexData.Large_binary_data, bstd.SizeBytes) + 2 - s += bstd.SizeSlice(complexData.Huge_list, bstd.SizeInt64) + 2 - - if id > 255 { - s += 5 - return - } - s += 4 - return -} - -// SizePlain - ComplexData -func (complexData *ComplexData) SizePlain() (s int) { - s += bstd.SizeInt(complexData.Id) - s += bstd.SizeString(complexData.Title) - s += bstd.SizeSlice(complexData.Items, func (s SubItem) int { return s.SizePlain() }) - s += bstd.SizeMap(complexData.Metadata, bstd.SizeString, bstd.SizeInt32) - s += complexData.Sub_data.SizePlain() - s += bstd.SizeSlice(complexData.Large_binary_data, bstd.SizeBytes) - s += bstd.SizeSlice(complexData.Huge_list, bstd.SizeInt64) - return -} - -// Marshal - ComplexData -func (complexData *ComplexData) Marshal(b []byte) { - complexData.marshal(0, b, 0) -} - -// Nested Marshal - ComplexData -func (complexData *ComplexData) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Varint, 1) - n = bstd.MarshalInt(n, b, complexData.Id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalString(n, b, complexData.Title) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) - n = bstd.MarshalSlice(n, b, complexData.Items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 4) - n = bstd.MarshalMap(n, b, complexData.Metadata, bstd.MarshalString, bstd.MarshalInt32) - n = complexData.Sub_data.marshal(n, b, 5) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 6) - n = bstd.MarshalSlice(n, b, complexData.Large_binary_data, bstd.MarshalBytes) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 7) - n = bstd.MarshalSlice(n, b, complexData.Huge_list, bstd.MarshalInt64) - - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} - -// MarshalPlain - ComplexData -func (complexData *ComplexData) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalInt(n, b, complexData.Id) - n = bstd.MarshalString(n, b, complexData.Title) - n = bstd.MarshalSlice(n, b, complexData.Items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) - n = bstd.MarshalMap(n, b, complexData.Metadata, bstd.MarshalString, bstd.MarshalInt32) - n = complexData.Sub_data.MarshalPlain(n, b) - n = bstd.MarshalSlice(n, b, complexData.Large_binary_data, bstd.MarshalBytes) - n = bstd.MarshalSlice(n, b, complexData.Huge_list, bstd.MarshalInt64) - return n -} - -// Unmarshal - ComplexData -func (complexData *ComplexData) Unmarshal(b []byte) (err error) { - _, err = complexData.unmarshal(0, b, []uint16{}, 0) - return -} - -// Nested Unmarshal - ComplexData -func (complexData *ComplexData) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, complexData.Id, err = bstd.UnmarshalInt(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, complexData.Title, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 3); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, complexData.Items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 4); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, complexData.Metadata, err = bstd.UnmarshalMap[string, int32](n, b, bstd.UnmarshalString, bstd.UnmarshalInt32); err != nil { - return - } - } - if n, err = complexData.Sub_data.unmarshal(n, b, complexDataRIds, 5); err != nil { - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 6); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, complexData.Large_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, complexDataRIds, 7); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, complexData.Huge_list, err = bstd.UnmarshalSlice[int64](n, b, bstd.UnmarshalInt64); err != nil { - return - } - } - n += 2 - return -} - -// UnmarshalPlain - ComplexData -func (complexData *ComplexData) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, complexData.Id, err = bstd.UnmarshalInt(n, b); err != nil { - return - } - if n, complexData.Title, err = bstd.UnmarshalString(n, b); err != nil { - return - } - if n, complexData.Items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { - return - } - if n, complexData.Metadata, err = bstd.UnmarshalMap[string, int32](n, b, bstd.UnmarshalString, bstd.UnmarshalInt32); err != nil { - return - } - if n, err = complexData.Sub_data.UnmarshalPlain(n, b); err != nil { - return - } - if n, complexData.Large_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { - return - } - if n, complexData.Huge_list, err = bstd.UnmarshalSlice[int64](n, b, bstd.UnmarshalInt64); err != nil { - return - } - return -} - -// Struct - SubItem -type SubItem struct { - Sub_id int32 - Description string - Sub_items []SubSubItem -} - -// Reserved Ids - SubItem -var subItemRIds = []uint16{} - -// Size - SubItem -func (subItem *SubItem) Size() int { - return subItem.size(0) -} - -// Nested Size - SubItem -func (subItem *SubItem) size(id uint16) (s int) { - s += bstd.SizeInt32() + 2 - s += bstd.SizeString(subItem.Description) + 2 - s += bstd.SizeSlice(subItem.Sub_items, func (s SubSubItem) int { return s.SizePlain() }) + 2 - - if id > 255 { - s += 5 - return - } - s += 4 - return -} - -// SizePlain - SubItem -func (subItem *SubItem) SizePlain() (s int) { - s += bstd.SizeInt32() - s += bstd.SizeString(subItem.Description) - s += bstd.SizeSlice(subItem.Sub_items, func (s SubSubItem) int { return s.SizePlain() }) - return -} - -// Marshal - SubItem -func (subItem *SubItem) Marshal(b []byte) { - subItem.marshal(0, b, 0) -} - -// Nested Marshal - SubItem -func (subItem *SubItem) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed32, 1) - n = bstd.MarshalInt32(n, b, subItem.Sub_id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalString(n, b, subItem.Description) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) - n = bstd.MarshalSlice(n, b, subItem.Sub_items, func (n int, b []byte, s SubSubItem) int { return s.MarshalPlain(n, b) }) - - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} - -// MarshalPlain - SubItem -func (subItem *SubItem) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalInt32(n, b, subItem.Sub_id) - n = bstd.MarshalString(n, b, subItem.Description) - n = bstd.MarshalSlice(n, b, subItem.Sub_items, func (n int, b []byte, s SubSubItem) int { return s.MarshalPlain(n, b) }) - return n -} - -// Unmarshal - SubItem -func (subItem *SubItem) Unmarshal(b []byte) (err error) { - _, err = subItem.unmarshal(0, b, []uint16{}, 0) - return -} - -// Nested Unmarshal - SubItem -func (subItem *SubItem) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subItemRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subItem.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subItemRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subItem.Description, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subItemRIds, 3); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subItem.Sub_items, err = bstd.UnmarshalSlice[SubSubItem](n, b, func (n int, b []byte, s *SubSubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { - return - } - } - n += 2 - return -} - -// UnmarshalPlain - SubItem -func (subItem *SubItem) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, subItem.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { - return - } - if n, subItem.Description, err = bstd.UnmarshalString(n, b); err != nil { - return - } - if n, subItem.Sub_items, err = bstd.UnmarshalSlice[SubSubItem](n, b, func (n int, b []byte, s *SubSubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { - return - } - return -} - -// Struct - SubSubItem -type SubSubItem struct { - Sub_sub_id string - Sub_sub_data []byte -} - -// Reserved Ids - SubSubItem -var subSubItemRIds = []uint16{} - -// Size - SubSubItem -func (subSubItem *SubSubItem) Size() int { - return subSubItem.size(0) -} - -// Nested Size - SubSubItem -func (subSubItem *SubSubItem) size(id uint16) (s int) { - s += bstd.SizeString(subSubItem.Sub_sub_id) + 2 - s += bstd.SizeBytes(subSubItem.Sub_sub_data) + 2 - - if id > 255 { - s += 5 - return - } - s += 4 - return -} - -// SizePlain - SubSubItem -func (subSubItem *SubSubItem) SizePlain() (s int) { - s += bstd.SizeString(subSubItem.Sub_sub_id) - s += bstd.SizeBytes(subSubItem.Sub_sub_data) - return -} - -// Marshal - SubSubItem -func (subSubItem *SubSubItem) Marshal(b []byte) { - subSubItem.marshal(0, b, 0) -} - -// Nested Marshal - SubSubItem -func (subSubItem *SubSubItem) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 1) - n = bstd.MarshalString(n, b, subSubItem.Sub_sub_id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalBytes(n, b, subSubItem.Sub_sub_data) - - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} - -// MarshalPlain - SubSubItem -func (subSubItem *SubSubItem) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalString(n, b, subSubItem.Sub_sub_id) - n = bstd.MarshalBytes(n, b, subSubItem.Sub_sub_data) - return n -} - -// Unmarshal - SubSubItem -func (subSubItem *SubSubItem) Unmarshal(b []byte) (err error) { - _, err = subSubItem.unmarshal(0, b, []uint16{}, 0) - return -} - -// Nested Unmarshal - SubSubItem -func (subSubItem *SubSubItem) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subSubItemRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subSubItem.Sub_sub_id, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subSubItemRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subSubItem.Sub_sub_data, err = bstd.UnmarshalBytes(n, b); err != nil { - return - } - } - n += 2 - return -} - -// UnmarshalPlain - SubSubItem -func (subSubItem *SubSubItem) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, subSubItem.Sub_sub_id, err = bstd.UnmarshalString(n, b); err != nil { - return - } - if n, subSubItem.Sub_sub_data, err = bstd.UnmarshalBytes(n, b); err != nil { - return - } - return -} - -// Struct - SubComplexData -type SubComplexData struct { - Sub_id int32 - Sub_title string - Sub_binary_data [][]byte - Sub_items []SubItem - Sub_metadata map[string]string -} - -// Reserved Ids - SubComplexData -var subComplexDataRIds = []uint16{} - -// Size - SubComplexData -func (subComplexData *SubComplexData) Size() int { - return subComplexData.size(0) -} - -// Nested Size - SubComplexData -func (subComplexData *SubComplexData) size(id uint16) (s int) { - s += bstd.SizeInt32() + 2 - s += bstd.SizeString(subComplexData.Sub_title) + 2 - s += bstd.SizeSlice(subComplexData.Sub_binary_data, bstd.SizeBytes) + 2 - s += bstd.SizeSlice(subComplexData.Sub_items, func (s SubItem) int { return s.SizePlain() }) + 2 - s += bstd.SizeMap(subComplexData.Sub_metadata, bstd.SizeString, bstd.SizeString) + 2 - - if id > 255 { - s += 5 - return - } - s += 4 - return -} - -// SizePlain - SubComplexData -func (subComplexData *SubComplexData) SizePlain() (s int) { - s += bstd.SizeInt32() - s += bstd.SizeString(subComplexData.Sub_title) - s += bstd.SizeSlice(subComplexData.Sub_binary_data, bstd.SizeBytes) - s += bstd.SizeSlice(subComplexData.Sub_items, func (s SubItem) int { return s.SizePlain() }) - s += bstd.SizeMap(subComplexData.Sub_metadata, bstd.SizeString, bstd.SizeString) - return -} - -// Marshal - SubComplexData -func (subComplexData *SubComplexData) Marshal(b []byte) { - subComplexData.marshal(0, b, 0) -} - -// Nested Marshal - SubComplexData -func (subComplexData *SubComplexData) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed32, 1) - n = bstd.MarshalInt32(n, b, subComplexData.Sub_id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalString(n, b, subComplexData.Sub_title) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) - n = bstd.MarshalSlice(n, b, subComplexData.Sub_binary_data, bstd.MarshalBytes) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 4) - n = bstd.MarshalSlice(n, b, subComplexData.Sub_items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 5) - n = bstd.MarshalMap(n, b, subComplexData.Sub_metadata, bstd.MarshalString, bstd.MarshalString) - - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} - -// MarshalPlain - SubComplexData -func (subComplexData *SubComplexData) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalInt32(n, b, subComplexData.Sub_id) - n = bstd.MarshalString(n, b, subComplexData.Sub_title) - n = bstd.MarshalSlice(n, b, subComplexData.Sub_binary_data, bstd.MarshalBytes) - n = bstd.MarshalSlice(n, b, subComplexData.Sub_items, func (n int, b []byte, s SubItem) int { return s.MarshalPlain(n, b) }) - n = bstd.MarshalMap(n, b, subComplexData.Sub_metadata, bstd.MarshalString, bstd.MarshalString) - return n -} - -// Unmarshal - SubComplexData -func (subComplexData *SubComplexData) Unmarshal(b []byte) (err error) { - _, err = subComplexData.unmarshal(0, b, []uint16{}, 0) - return -} - -// Nested Unmarshal - SubComplexData -func (subComplexData *SubComplexData) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subComplexData.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subComplexData.Sub_title, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 3); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subComplexData.Sub_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 4); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subComplexData.Sub_items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, subComplexDataRIds, 5); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, subComplexData.Sub_metadata, err = bstd.UnmarshalMap[string, string](n, b, bstd.UnmarshalString, bstd.UnmarshalString); err != nil { - return - } - } - n += 2 - return -} - -// UnmarshalPlain - SubComplexData -func (subComplexData *SubComplexData) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, subComplexData.Sub_id, err = bstd.UnmarshalInt32(n, b); err != nil { - return - } - if n, subComplexData.Sub_title, err = bstd.UnmarshalString(n, b); err != nil { - return - } - if n, subComplexData.Sub_binary_data, err = bstd.UnmarshalSlice[[]byte](n, b, bstd.UnmarshalBytes); err != nil { - return - } - if n, subComplexData.Sub_items, err = bstd.UnmarshalSlice[SubItem](n, b, func (n int, b []byte, s *SubItem) (int, error) { return s.UnmarshalPlain(n, b) }); err != nil { - return - } - if n, subComplexData.Sub_metadata, err = bstd.UnmarshalMap[string, string](n, b, bstd.UnmarshalString, bstd.UnmarshalString); err != nil { - return - } - return -} - diff --git a/testing/complex_data/complex_test.go b/testing/complex_data/complex_test.go deleted file mode 100644 index 8aa5d6f..0000000 --- a/testing/complex_data/complex_test.go +++ /dev/null @@ -1,138 +0,0 @@ -//go:generate bencgen --in ../schemas/complex_data.benc --out ./ --file complex_data_test --lang go - -package complex_data - -import ( - "fmt" - "reflect" - "testing" -) - -func TestComplex(t *testing.T) { - data := ComplexData{ - Id: 12345, - Title: "Example Complex Data", - Items: []SubItem{ - { - Sub_id: 1, - Description: "SubItem 1", - Sub_items: []SubSubItem{ - { - Sub_sub_id: "subsub1", - Sub_sub_data: []byte{0x01, 0x02, 0x03}, - }, - }, - }, - }, - Metadata: map[string]int32{ - "key1": 10, - "key2": 20, - }, - Sub_data: SubComplexData{ - Sub_id: 999, - Sub_title: "Sub Complex Data", - Sub_binary_data: [][]byte{ - {0x11, 0x22, 0x33}, - {0x44, 0x55, 0x66}, - }, - Sub_items: []SubItem{ - { - Sub_id: 2, - Description: "SubItem 2", - Sub_items: []SubSubItem{ - { - Sub_sub_id: "subsub2", - Sub_sub_data: []byte{0xAA, 0xBB, 0xCC}, - }, - }, - }, - }, - Sub_metadata: map[string]string{ - "meta1": "value1", - "meta2": "value2", - }, - }, - Large_binary_data: [][]byte{ - {0xFF, 0xEE, 0xDD}, - }, - Huge_list: []int64{1000000, 2000000, 3000000}, - } - - s := data.Size() - b := make([]byte, s) - data.Marshal(b) - fmt.Println(b) - - var retData ComplexData - if err := retData.Unmarshal(b); err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(data, retData) { - t.Fatalf("no match\norg: %v\ndec: %v\n", data, retData) - } -} - -func BenchmarkComplex(b *testing.B) { - data := ComplexData{ - Id: 12345, - Title: "Example Complex Data", - Items: []SubItem{ - { - Sub_id: 1, - Description: "SubItem 1", - Sub_items: []SubSubItem{ - { - Sub_sub_id: "subsub1", - Sub_sub_data: []byte{0x01, 0x02, 0x03}, - }, - }, - }, - }, - Metadata: map[string]int32{ - "key1": 10, - "key2": 20, - }, - Sub_data: SubComplexData{ - Sub_id: 999, - Sub_title: "Sub Complex Data", - Sub_binary_data: [][]byte{ - {0x11, 0x22, 0x33}, - {0x44, 0x55, 0x66}, - }, - Sub_items: []SubItem{ - { - Sub_id: 2, - Description: "SubItem 2", - Sub_items: []SubSubItem{ - { - Sub_sub_id: "subsub2", - Sub_sub_data: []byte{0xAA, 0xBB, 0xCC}, - }, - }, - }, - }, - Sub_metadata: map[string]string{ - "meta1": "value1", - "meta2": "value2", - }, - }, - Large_binary_data: [][]byte{ - {0xFF, 0xEE, 0xDD}, - }, - Huge_list: []int64{1000000, 2000000, 3000000}, - } - b.ReportAllocs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - s := data.Size() - buf := make([]byte, s) - data.Marshal(buf) - - var retData ComplexData - if err := retData.Unmarshal(buf); err != nil { - b.Fatal(err) - } - } -} diff --git a/testing/others/main_others_test.go b/testing/others/main_others_test.go deleted file mode 100644 index 187fcb2..0000000 --- a/testing/others/main_others_test.go +++ /dev/null @@ -1,51 +0,0 @@ -//go:generate bencgen --in ../schemas/others.benc --out ./ --file others_test --lang go - -package others - -import ( - "math/rand" - "reflect" - "testing" -) - -func TestUint(t *testing.T) { - ui64 := rand.Uint64() - ui32 := rand.Uint32() - ui16 := uint16(65000) - ui := uint(rand.Uint64()) - - ui64Arr := []uint64{rand.Uint64(), rand.Uint64(), rand.Uint64()} - - ui64Map := make(map[uint64]uint32) - ui64Map[rand.Uint64()] = rand.Uint32() - ui64Map[rand.Uint64()] = rand.Uint32() - ui64Map[rand.Uint64()] = rand.Uint32() - - data := OthersTest{ - Ui64: ui64, - Ui32: ui32, - Ui16: ui16, - Ui: ui, - - Ui64Arr: ui64Arr, - Ui64Map: ui64Map, - - ExampleEnum: ExampleEnumOne, - ExampleEnum2: ExampleEnum2Six, - } - - buf := make([]byte, data.Size()) - data.Marshal(buf) - - var deserData OthersTest - err := deserData.Unmarshal(buf) - if err != nil { - t.Fatal(err) - } - - if !reflect.DeepEqual(deserData, data) { - t.Logf("%v", deserData) - t.Logf("%v", data) - t.Errorf("Deserialized- and original data don't match!") - } -} diff --git a/testing/others/others.go b/testing/others/others.go new file mode 100644 index 0000000..23c1f6f --- /dev/null +++ b/testing/others/others.go @@ -0,0 +1,284 @@ +// Code generated by bencgen go. DO NOT EDIT. +// source: ../schemas/others.benc + +package others + +import ( + "github.com/deneonet/benc/std" + "github.com/deneonet/benc/impl/gen" + + "github.com/deneonet/benc/testing/person" +) + +// Enum - ExampleEnum +type ExampleEnum int +const ( + ExampleEnumOne ExampleEnum = iota + ExampleEnumTwo + ExampleEnumThree + ExampleEnumFour +) + +// Enum - ExampleEnum2 +type ExampleEnum2 int +const ( + ExampleEnum2Five ExampleEnum2 = iota + ExampleEnum2Six +) + +// Struct - OthersTest +type OthersTest struct { + Ui uint + Ui64 uint64 + Ui64Arr []uint64 + Ui64Map map[uint64]uint32 + Ui32 uint32 + Ui16 uint16 + ExampleEnum ExampleEnum + ExampleEnum2 ExampleEnum2 + Person person.Person + Person2 person.Person2 +} + +// Reserved Ids - OthersTest +var othersTestRIds = []uint16{} + +// Size - OthersTest +func (othersTest *OthersTest) Size() int { + return othersTest.NestedSize(0) +} + +// Nested Size - OthersTest +func (othersTest *OthersTest) NestedSize(id uint16) (s int) { + s += bstd.SizeUint(othersTest.Ui) + 2 + s += bstd.SizeUint64() + 2 + s += bstd.SizeSlice(othersTest.Ui64Arr, bstd.SizeUint64) + 2 + s += bstd.SizeMap(othersTest.Ui64Map, bstd.SizeUint64, bstd.SizeUint32) + 2 + s += bstd.SizeUint32() + 2 + s += bstd.SizeUint16() + 2 + s += bgenimpl.SizeEnum(othersTest.ExampleEnum) + 2 + s += bgenimpl.SizeEnum(othersTest.ExampleEnum2) + 2 + s += othersTest.Person.NestedSize(9) + s += othersTest.Person2.NestedSize(10) + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - OthersTest +func (othersTest *OthersTest) SizePlain() (s int) { + s += bstd.SizeUint(othersTest.Ui) + s += bstd.SizeUint64() + s += bstd.SizeSlice(othersTest.Ui64Arr, bstd.SizeUint64) + s += bstd.SizeMap(othersTest.Ui64Map, bstd.SizeUint64, bstd.SizeUint32) + s += bstd.SizeUint32() + s += bstd.SizeUint16() + s += bgenimpl.SizeEnum(othersTest.ExampleEnum) + s += bgenimpl.SizeEnum(othersTest.ExampleEnum2) + s += othersTest.Person.SizePlain() + s += othersTest.Person2.SizePlain() + return +} + +// Marshal - OthersTest +func (othersTest *OthersTest) Marshal(b []byte) { + othersTest.NestedMarshal(0, b, 0) +} + +// Nested Marshal - OthersTest +func (othersTest *OthersTest) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Varint, 1) + n = bstd.MarshalUint(n, b, othersTest.Ui) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed64, 2) + n = bstd.MarshalUint64(n, b, othersTest.Ui64) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) + n = bstd.MarshalSlice(n, b, othersTest.Ui64Arr, bstd.MarshalUint64) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 4) + n = bstd.MarshalMap(n, b, othersTest.Ui64Map, bstd.MarshalUint64, bstd.MarshalUint32) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed32, 5) + n = bstd.MarshalUint32(n, b, othersTest.Ui32) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed16, 6) + n = bstd.MarshalUint16(n, b, othersTest.Ui16) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 7) + n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum) + n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 8) + n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum2) + n = othersTest.Person.NestedMarshal(n, b, 9) + n = othersTest.Person2.NestedMarshal(n, b, 10) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - OthersTest +func (othersTest *OthersTest) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalUint(n, b, othersTest.Ui) + n = bstd.MarshalUint64(n, b, othersTest.Ui64) + n = bstd.MarshalSlice(n, b, othersTest.Ui64Arr, bstd.MarshalUint64) + n = bstd.MarshalMap(n, b, othersTest.Ui64Map, bstd.MarshalUint64, bstd.MarshalUint32) + n = bstd.MarshalUint32(n, b, othersTest.Ui32) + n = bstd.MarshalUint16(n, b, othersTest.Ui16) + n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum) + n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum2) + n = othersTest.Person.MarshalPlain(n, b) + n = othersTest.Person2.MarshalPlain(n, b) + return n +} + +// Unmarshal - OthersTest +func (othersTest *OthersTest) Unmarshal(b []byte) (err error) { + _, err = othersTest.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - OthersTest +func (othersTest *OthersTest) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.Ui, err = bstd.UnmarshalUint(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.Ui64, err = bstd.UnmarshalUint64(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 3); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.Ui64Arr, err = bstd.UnmarshalSlice[uint64](n, b, bstd.UnmarshalUint64); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 4); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.Ui64Map, err = bstd.UnmarshalMap[uint64, uint32](n, b, bstd.UnmarshalUint64, bstd.UnmarshalUint32); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 5); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.Ui32, err = bstd.UnmarshalUint32(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 6); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.Ui16, err = bstd.UnmarshalUint16(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 7); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.ExampleEnum, err = bgenimpl.UnmarshalEnum[ExampleEnum](n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 8); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, othersTest.ExampleEnum2, err = bgenimpl.UnmarshalEnum[ExampleEnum2](n, b); err != nil { + return + } + } + if n, err = othersTest.Person.NestedUnmarshal(n, b, othersTestRIds, 9); err != nil { + return + } + if n, err = othersTest.Person2.NestedUnmarshal(n, b, othersTestRIds, 10); err != nil { + return + } + n += 2 + return +} + +// UnmarshalPlain - OthersTest +func (othersTest *OthersTest) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, othersTest.Ui, err = bstd.UnmarshalUint(n, b); err != nil { + return + } + if n, othersTest.Ui64, err = bstd.UnmarshalUint64(n, b); err != nil { + return + } + if n, othersTest.Ui64Arr, err = bstd.UnmarshalSlice[uint64](n, b, bstd.UnmarshalUint64); err != nil { + return + } + if n, othersTest.Ui64Map, err = bstd.UnmarshalMap[uint64, uint32](n, b, bstd.UnmarshalUint64, bstd.UnmarshalUint32); err != nil { + return + } + if n, othersTest.Ui32, err = bstd.UnmarshalUint32(n, b); err != nil { + return + } + if n, othersTest.Ui16, err = bstd.UnmarshalUint16(n, b); err != nil { + return + } + if n, othersTest.ExampleEnum, err = bgenimpl.UnmarshalEnum[ExampleEnum](n, b); err != nil { + return + } + if n, othersTest.ExampleEnum2, err = bgenimpl.UnmarshalEnum[ExampleEnum2](n, b); err != nil { + return + } + if n, err = othersTest.Person.UnmarshalPlain(n, b); err != nil { + return + } + if n, err = othersTest.Person2.UnmarshalPlain(n, b); err != nil { + return + } + return +} + diff --git a/testing/others/others_test.go b/testing/others/others_test.go index 1b35c9d..eb470be 100644 --- a/testing/others/others_test.go +++ b/testing/others/others_test.go @@ -1,260 +1,51 @@ -// Code generated by bencgen go. DO NOT EDIT. -// source: ../schemas/others.benc +//go:generate bencgen --in ../schemas/others.benc --out ./ --file ... --lang go --import-dir ../schemas package others import ( - "github.com/deneonet/benc/std" - "github.com/deneonet/benc/impl/gen" + "math/rand" + "reflect" + "testing" ) -// Enum - ExampleEnum -type ExampleEnum int -const ( - ExampleEnumOne ExampleEnum = iota - ExampleEnumTwo - ExampleEnumThree - ExampleEnumFour -) - -// Enum - ExampleEnum2 -type ExampleEnum2 int -const ( - ExampleEnum2Five ExampleEnum2 = iota - ExampleEnum2Six -) - -// Struct - OthersTest -type OthersTest struct { - Ui64 uint64 - Ui64Arr []uint64 - Ui64Map map[uint64]uint32 - Ui32 uint32 - Ui16 uint16 - Ui uint - ExampleEnum ExampleEnum - ExampleEnum2 ExampleEnum2 -} - -// Reserved Ids - OthersTest -var othersTestRIds = []uint16{} - -// Size - OthersTest -func (othersTest *OthersTest) Size() int { - return othersTest.size(0) -} - -// Nested Size - OthersTest -func (othersTest *OthersTest) size(id uint16) (s int) { - s += bstd.SizeUint64() + 2 - s += bstd.SizeSlice(othersTest.Ui64Arr, bstd.SizeUint64) + 2 - s += bstd.SizeMap(othersTest.Ui64Map, bstd.SizeUint64, bstd.SizeUint32) + 2 - s += bstd.SizeUint32() + 2 - s += bstd.SizeUint16() + 2 - s += bstd.SizeUint(othersTest.Ui) + 2 - s += bgenimpl.SizeEnum(othersTest.ExampleEnum) + 2 - s += bgenimpl.SizeEnum(othersTest.ExampleEnum2) + 2 +func TestUint(t *testing.T) { + ui64 := rand.Uint64() + ui32 := rand.Uint32() + ui16 := uint16(65000) + ui := uint(rand.Uint64()) - if id > 255 { - s += 5 - return - } - s += 4 - return -} + ui64Arr := []uint64{rand.Uint64(), rand.Uint64(), rand.Uint64()} -// SizePlain - OthersTest -func (othersTest *OthersTest) SizePlain() (s int) { - s += bstd.SizeUint64() - s += bstd.SizeSlice(othersTest.Ui64Arr, bstd.SizeUint64) - s += bstd.SizeMap(othersTest.Ui64Map, bstd.SizeUint64, bstd.SizeUint32) - s += bstd.SizeUint32() - s += bstd.SizeUint16() - s += bstd.SizeUint(othersTest.Ui) - s += bgenimpl.SizeEnum(othersTest.ExampleEnum) - s += bgenimpl.SizeEnum(othersTest.ExampleEnum2) - return -} + ui64Map := make(map[uint64]uint32) + ui64Map[rand.Uint64()] = rand.Uint32() + ui64Map[rand.Uint64()] = rand.Uint32() + ui64Map[rand.Uint64()] = rand.Uint32() -// Marshal - OthersTest -func (othersTest *OthersTest) Marshal(b []byte) { - othersTest.marshal(0, b, 0) -} + data := OthersTest{ + Ui64: ui64, + Ui32: ui32, + Ui16: ui16, + Ui: ui, -// Nested Marshal - OthersTest -func (othersTest *OthersTest) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed64, 1) - n = bstd.MarshalUint64(n, b, othersTest.Ui64) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 2) - n = bstd.MarshalSlice(n, b, othersTest.Ui64Arr, bstd.MarshalUint64) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 3) - n = bstd.MarshalMap(n, b, othersTest.Ui64Map, bstd.MarshalUint64, bstd.MarshalUint32) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed32, 4) - n = bstd.MarshalUint32(n, b, othersTest.Ui32) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed16, 5) - n = bstd.MarshalUint16(n, b, othersTest.Ui16) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Varint, 7) - n = bstd.MarshalUint(n, b, othersTest.Ui) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 8) - n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum) - n = bgenimpl.MarshalTag(n, b, bgenimpl.ArrayMap, 9) - n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum2) + Ui64Arr: ui64Arr, + Ui64Map: ui64Map, - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} + ExampleEnum: ExampleEnumOne, + ExampleEnum2: ExampleEnum2Six, + } -// MarshalPlain - OthersTest -func (othersTest *OthersTest) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalUint64(n, b, othersTest.Ui64) - n = bstd.MarshalSlice(n, b, othersTest.Ui64Arr, bstd.MarshalUint64) - n = bstd.MarshalMap(n, b, othersTest.Ui64Map, bstd.MarshalUint64, bstd.MarshalUint32) - n = bstd.MarshalUint32(n, b, othersTest.Ui32) - n = bstd.MarshalUint16(n, b, othersTest.Ui16) - n = bstd.MarshalUint(n, b, othersTest.Ui) - n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum) - n = bgenimpl.MarshalEnum(n, b, othersTest.ExampleEnum2) - return n -} + buf := make([]byte, data.Size()) + data.Marshal(buf) -// Unmarshal - OthersTest -func (othersTest *OthersTest) Unmarshal(b []byte) (err error) { - _, err = othersTest.unmarshal(0, b, []uint16{}, 0) - return -} - -// Nested Unmarshal - OthersTest -func (othersTest *OthersTest) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.Ui64, err = bstd.UnmarshalUint64(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.Ui64Arr, err = bstd.UnmarshalSlice[uint64](n, b, bstd.UnmarshalUint64); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 3); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.Ui64Map, err = bstd.UnmarshalMap[uint64, uint32](n, b, bstd.UnmarshalUint64, bstd.UnmarshalUint32); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 4); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.Ui32, err = bstd.UnmarshalUint32(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 5); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.Ui16, err = bstd.UnmarshalUint16(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 7); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.Ui, err = bstd.UnmarshalUint(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 8); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.ExampleEnum, err = bgenimpl.UnmarshalEnum[ExampleEnum](n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, othersTestRIds, 9); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, othersTest.ExampleEnum2, err = bgenimpl.UnmarshalEnum[ExampleEnum2](n, b); err != nil { - return - } - } - n += 2 - return -} + var deserData OthersTest + err := deserData.Unmarshal(buf) + if err != nil { + t.Fatal(err) + } -// UnmarshalPlain - OthersTest -func (othersTest *OthersTest) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, othersTest.Ui64, err = bstd.UnmarshalUint64(n, b); err != nil { - return - } - if n, othersTest.Ui64Arr, err = bstd.UnmarshalSlice[uint64](n, b, bstd.UnmarshalUint64); err != nil { - return - } - if n, othersTest.Ui64Map, err = bstd.UnmarshalMap[uint64, uint32](n, b, bstd.UnmarshalUint64, bstd.UnmarshalUint32); err != nil { - return - } - if n, othersTest.Ui32, err = bstd.UnmarshalUint32(n, b); err != nil { - return - } - if n, othersTest.Ui16, err = bstd.UnmarshalUint16(n, b); err != nil { - return - } - if n, othersTest.Ui, err = bstd.UnmarshalUint(n, b); err != nil { - return - } - if n, othersTest.ExampleEnum, err = bgenimpl.UnmarshalEnum[ExampleEnum](n, b); err != nil { - return - } - if n, othersTest.ExampleEnum2, err = bgenimpl.UnmarshalEnum[ExampleEnum2](n, b); err != nil { - return - } - return + if !reflect.DeepEqual(deserData, data) { + t.Logf("%v", deserData) + t.Logf("%v", data) + t.Errorf("Deserialized- and original data don't match!") + } } - diff --git a/testing/person/main_person_test.go b/testing/person/main_person_test.go deleted file mode 100644 index c0d9a4c..0000000 --- a/testing/person/main_person_test.go +++ /dev/null @@ -1,124 +0,0 @@ -//go:generate bencgen --in ../schemas/person.benc --out ./ --file person_test --lang go -//go:generate bencgen --in ../schemas/person2.benc --out ./ --file person2_test --lang go - -package person - -import "testing" - -// Forward compatibility -func TestPersonToPerson2(t *testing.T) { - originalPerson := Person{ - Age: 30, - Name: "John Doe", - Parents: Parents{ - Mother: "Jane Doe", - Father: "John Smith", - }, - Child: Child{ - Age: 10, - Name: "Junior Doe", - Parents: Parents{ - Mother: "Jane Doe", - Father: "John Doe", - }, - }, - } - - expectedPerson2 := Person2{ - Age: 30, - Name: "John Doe", - Child: Child2{ - Age: 10, - Name: "Junior Doe", - Parents: Parents2{ - Mother: "Jane Doe", - Father: "John Doe", - }, - }, - } - - buf := make([]byte, originalPerson.Size()) - originalPerson.Marshal(buf) - - var deserPerson2 Person2 - err := deserPerson2.Unmarshal(buf) - if err != nil { - t.Fatal(err) - } - - if deserPerson2.Age != expectedPerson2.Age { - t.Errorf("Expected Age %d, got %d", expectedPerson2.Age, deserPerson2.Age) - } - if deserPerson2.Name != expectedPerson2.Name { - t.Errorf("Expected Name %s, got %s", expectedPerson2.Name, deserPerson2.Name) - } - if deserPerson2.Child.Age != expectedPerson2.Child.Age { - t.Errorf("Expected Child Age %d, got %d", expectedPerson2.Child.Age, deserPerson2.Child.Age) - } - if deserPerson2.Child.Name != expectedPerson2.Child.Name { - t.Errorf("Expected Child Name %s, got %s", expectedPerson2.Child.Name, deserPerson2.Child.Name) - } - if deserPerson2.Child.Parents.Mother != expectedPerson2.Child.Parents.Mother { - t.Errorf("Expected Child's Mother %s, got %s", expectedPerson2.Child.Parents.Mother, deserPerson2.Child.Parents.Mother) - } - if deserPerson2.Child.Parents.Father != expectedPerson2.Child.Parents.Father { - t.Errorf("Expected Child's Father %s, got %s", expectedPerson2.Child.Parents.Father, deserPerson2.Child.Parents.Father) - } -} - -// Backward compatibility -func TestPerson2ToPerson(t *testing.T) { - originalPerson2 := Person2{ - Age: 30, - Name: "John Doe", - Child: Child2{ - Age: 10, - Name: "Junior Doe", - Parents: Parents2{ - Mother: "Jane Doe", - Father: "John Doe", - }, - }, - } - - expectedPerson := Person{ - Age: 30, - Name: "John Doe", - Child: Child{ - Age: 10, - Name: "Junior Doe", - Parents: Parents{ - Mother: "Jane Doe", - Father: "John Doe", - }, - }, - } - - buf := make([]byte, originalPerson2.Size()) - originalPerson2.Marshal(buf) - - var deserPerson Person - err := deserPerson.Unmarshal(buf) - if err != nil { - t.Fatal(err) - } - - if deserPerson.Age != expectedPerson.Age { - t.Errorf("Expected Age %d, got %d", expectedPerson.Age, deserPerson.Age) - } - if deserPerson.Name != expectedPerson.Name { - t.Errorf("Expected Name %s, got %s", expectedPerson.Name, deserPerson.Name) - } - if deserPerson.Child.Age != expectedPerson.Child.Age { - t.Errorf("Expected Child Age %d, got %d", expectedPerson.Child.Age, deserPerson.Child.Age) - } - if deserPerson.Child.Name != expectedPerson.Child.Name { - t.Errorf("Expected Child Name %s, got %s", expectedPerson.Child.Name, deserPerson.Child.Name) - } - if deserPerson.Child.Parents.Mother != expectedPerson.Child.Parents.Mother { - t.Errorf("Expected Child's Mother %s, got %s", expectedPerson.Child.Parents.Mother, deserPerson.Child.Parents.Mother) - } - if deserPerson.Child.Parents.Father != expectedPerson.Child.Parents.Father { - t.Errorf("Expected Child's Father %s, got %s", expectedPerson.Child.Parents.Father, deserPerson.Child.Parents.Father) - } -} diff --git a/testing/person/person.go b/testing/person/person.go new file mode 100644 index 0000000..cd1e948 --- /dev/null +++ b/testing/person/person.go @@ -0,0 +1,387 @@ +// Code generated by bencgen go. DO NOT EDIT. +// source: ../schemas/person.benc + +package person + +import ( + "github.com/deneonet/benc/std" + "github.com/deneonet/benc/impl/gen" + + +) + +// Struct - Person +type Person struct { + Age byte + Name string + Parents Parents + Child Child +} + +// Reserved Ids - Person +var personRIds = []uint16{} + +// Size - Person +func (person *Person) Size() int { + return person.NestedSize(0) +} + +// Nested Size - Person +func (person *Person) NestedSize(id uint16) (s int) { + s += bstd.SizeByte() + 2 + s += bstd.SizeString(person.Name) + 2 + s += person.Parents.NestedSize(3) + s += person.Child.NestedSize(4) + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - Person +func (person *Person) SizePlain() (s int) { + s += bstd.SizeByte() + s += bstd.SizeString(person.Name) + s += person.Parents.SizePlain() + s += person.Child.SizePlain() + return +} + +// Marshal - Person +func (person *Person) Marshal(b []byte) { + person.NestedMarshal(0, b, 0) +} + +// Nested Marshal - Person +func (person *Person) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed8, 1) + n = bstd.MarshalByte(n, b, person.Age) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) + n = bstd.MarshalString(n, b, person.Name) + n = person.Parents.NestedMarshal(n, b, 3) + n = person.Child.NestedMarshal(n, b, 4) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - Person +func (person *Person) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalByte(n, b, person.Age) + n = bstd.MarshalString(n, b, person.Name) + n = person.Parents.MarshalPlain(n, b) + n = person.Child.MarshalPlain(n, b) + return n +} + +// Unmarshal - Person +func (person *Person) Unmarshal(b []byte) (err error) { + _, err = person.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - Person +func (person *Person) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, personRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, person.Age, err = bstd.UnmarshalByte(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, personRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, person.Name, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + if n, err = person.Parents.NestedUnmarshal(n, b, personRIds, 3); err != nil { + return + } + if n, err = person.Child.NestedUnmarshal(n, b, personRIds, 4); err != nil { + return + } + n += 2 + return +} + +// UnmarshalPlain - Person +func (person *Person) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, person.Age, err = bstd.UnmarshalByte(n, b); err != nil { + return + } + if n, person.Name, err = bstd.UnmarshalString(n, b); err != nil { + return + } + if n, err = person.Parents.UnmarshalPlain(n, b); err != nil { + return + } + if n, err = person.Child.UnmarshalPlain(n, b); err != nil { + return + } + return +} + +// Struct - Child +type Child struct { + Age byte + Name string + Parents Parents +} + +// Reserved Ids - Child +var childRIds = []uint16{} + +// Size - Child +func (child *Child) Size() int { + return child.NestedSize(0) +} + +// Nested Size - Child +func (child *Child) NestedSize(id uint16) (s int) { + s += bstd.SizeByte() + 2 + s += bstd.SizeString(child.Name) + 2 + s += child.Parents.NestedSize(3) + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - Child +func (child *Child) SizePlain() (s int) { + s += bstd.SizeByte() + s += bstd.SizeString(child.Name) + s += child.Parents.SizePlain() + return +} + +// Marshal - Child +func (child *Child) Marshal(b []byte) { + child.NestedMarshal(0, b, 0) +} + +// Nested Marshal - Child +func (child *Child) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed8, 1) + n = bstd.MarshalByte(n, b, child.Age) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) + n = bstd.MarshalString(n, b, child.Name) + n = child.Parents.NestedMarshal(n, b, 3) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - Child +func (child *Child) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalByte(n, b, child.Age) + n = bstd.MarshalString(n, b, child.Name) + n = child.Parents.MarshalPlain(n, b) + return n +} + +// Unmarshal - Child +func (child *Child) Unmarshal(b []byte) (err error) { + _, err = child.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - Child +func (child *Child) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, childRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, child.Age, err = bstd.UnmarshalByte(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, childRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, child.Name, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + if n, err = child.Parents.NestedUnmarshal(n, b, childRIds, 3); err != nil { + return + } + n += 2 + return +} + +// UnmarshalPlain - Child +func (child *Child) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, child.Age, err = bstd.UnmarshalByte(n, b); err != nil { + return + } + if n, child.Name, err = bstd.UnmarshalString(n, b); err != nil { + return + } + if n, err = child.Parents.UnmarshalPlain(n, b); err != nil { + return + } + return +} + +// Struct - Parents +type Parents struct { + Mother string + Father string +} + +// Reserved Ids - Parents +var parentsRIds = []uint16{} + +// Size - Parents +func (parents *Parents) Size() int { + return parents.NestedSize(0) +} + +// Nested Size - Parents +func (parents *Parents) NestedSize(id uint16) (s int) { + s += bstd.SizeString(parents.Mother) + 2 + s += bstd.SizeString(parents.Father) + 2 + + if id > 255 { + s += 5 + return + } + s += 4 + return +} + +// SizePlain - Parents +func (parents *Parents) SizePlain() (s int) { + s += bstd.SizeString(parents.Mother) + s += bstd.SizeString(parents.Father) + return +} + +// Marshal - Parents +func (parents *Parents) Marshal(b []byte) { + parents.NestedMarshal(0, b, 0) +} + +// Nested Marshal - Parents +func (parents *Parents) NestedMarshal(tn int, b []byte, id uint16) (n int) { + n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 1) + n = bstd.MarshalString(n, b, parents.Mother) + n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) + n = bstd.MarshalString(n, b, parents.Father) + + n += 2 + b[n-2] = 1 + b[n-1] = 1 + return +} + +// MarshalPlain - Parents +func (parents *Parents) MarshalPlain(tn int, b []byte) (n int) { + n = tn + n = bstd.MarshalString(n, b, parents.Mother) + n = bstd.MarshalString(n, b, parents.Father) + return n +} + +// Unmarshal - Parents +func (parents *Parents) Unmarshal(b []byte) (err error) { + _, err = parents.NestedUnmarshal(0, b, []uint16{}, 0) + return +} + +// Nested Unmarshal - Parents +func (parents *Parents) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { + var ok bool + if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, parentsRIds, 1); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, parents.Mother, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + if n, ok, err = bgenimpl.HandleCompatibility(n, b, parentsRIds, 2); err != nil { + if err == bgenimpl.ErrEof { + return n, nil + } + return + } + if ok { + if n, parents.Father, err = bstd.UnmarshalString(n, b); err != nil { + return + } + } + n += 2 + return +} + +// UnmarshalPlain - Parents +func (parents *Parents) UnmarshalPlain(tn int, b []byte) (n int, err error) { + n = tn + if n, parents.Mother, err = bstd.UnmarshalString(n, b); err != nil { + return + } + if n, parents.Father, err = bstd.UnmarshalString(n, b); err != nil { + return + } + return +} + diff --git a/testing/person/person2_test.go b/testing/person/person2.go similarity index 78% rename from testing/person/person2_test.go rename to testing/person/person2.go index dddd7ce..ce0bc4e 100644 --- a/testing/person/person2_test.go +++ b/testing/person/person2.go @@ -6,6 +6,8 @@ package person import ( "github.com/deneonet/benc/std" "github.com/deneonet/benc/impl/gen" + + ) // Struct - Person2 @@ -20,14 +22,14 @@ var person2RIds = []uint16{3} // Size - Person2 func (person2 *Person2) Size() int { - return person2.size(0) + return person2.NestedSize(0) } // Nested Size - Person2 -func (person2 *Person2) size(id uint16) (s int) { +func (person2 *Person2) NestedSize(id uint16) (s int) { s += bstd.SizeByte() + 2 s += bstd.SizeString(person2.Name) + 2 - s += person2.Child.size(4) + s += person2.Child.NestedSize(4) if id > 255 { s += 5 @@ -47,17 +49,17 @@ func (person2 *Person2) SizePlain() (s int) { // Marshal - Person2 func (person2 *Person2) Marshal(b []byte) { - person2.marshal(0, b, 0) + person2.NestedMarshal(0, b, 0) } // Nested Marshal - Person2 -func (person2 *Person2) marshal(tn int, b []byte, id uint16) (n int) { +func (person2 *Person2) NestedMarshal(tn int, b []byte, id uint16) (n int) { n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed8, 1) n = bstd.MarshalByte(n, b, person2.Age) n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) n = bstd.MarshalString(n, b, person2.Name) - n = person2.Child.marshal(n, b, 4) + n = person2.Child.NestedMarshal(n, b, 4) n += 2 b[n-2] = 1 @@ -76,12 +78,12 @@ func (person2 *Person2) MarshalPlain(tn int, b []byte) (n int) { // Unmarshal - Person2 func (person2 *Person2) Unmarshal(b []byte) (err error) { - _, err = person2.unmarshal(0, b, []uint16{}, 0) + _, err = person2.NestedUnmarshal(0, b, []uint16{}, 0) return } // Nested Unmarshal - Person2 -func (person2 *Person2) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { +func (person2 *Person2) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { var ok bool if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { if err == bgenimpl.ErrEof { @@ -111,7 +113,7 @@ func (person2 *Person2) unmarshal(tn int, b []byte, r []uint16, id uint16) (n in return } } - if n, err = person2.Child.unmarshal(n, b, person2RIds, 4); err != nil { + if n, err = person2.Child.NestedUnmarshal(n, b, person2RIds, 4); err != nil { return } n += 2 @@ -136,23 +138,21 @@ func (person2 *Person2) UnmarshalPlain(tn int, b []byte) (n int, err error) { // Struct - Child2 type Child2 struct { Age byte - Name string Parents Parents2 } // Reserved Ids - Child2 -var child2RIds = []uint16{} +var child2RIds = []uint16{2} // Size - Child2 func (child2 *Child2) Size() int { - return child2.size(0) + return child2.NestedSize(0) } // Nested Size - Child2 -func (child2 *Child2) size(id uint16) (s int) { +func (child2 *Child2) NestedSize(id uint16) (s int) { s += bstd.SizeByte() + 2 - s += bstd.SizeString(child2.Name) + 2 - s += child2.Parents.size(3) + s += child2.Parents.NestedSize(3) if id > 255 { s += 5 @@ -165,24 +165,21 @@ func (child2 *Child2) size(id uint16) (s int) { // SizePlain - Child2 func (child2 *Child2) SizePlain() (s int) { s += bstd.SizeByte() - s += bstd.SizeString(child2.Name) s += child2.Parents.SizePlain() return } // Marshal - Child2 func (child2 *Child2) Marshal(b []byte) { - child2.marshal(0, b, 0) + child2.NestedMarshal(0, b, 0) } // Nested Marshal - Child2 -func (child2 *Child2) marshal(tn int, b []byte, id uint16) (n int) { +func (child2 *Child2) NestedMarshal(tn int, b []byte, id uint16) (n int) { n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed8, 1) n = bstd.MarshalByte(n, b, child2.Age) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalString(n, b, child2.Name) - n = child2.Parents.marshal(n, b, 3) + n = child2.Parents.NestedMarshal(n, b, 3) n += 2 b[n-2] = 1 @@ -194,19 +191,18 @@ func (child2 *Child2) marshal(tn int, b []byte, id uint16) (n int) { func (child2 *Child2) MarshalPlain(tn int, b []byte) (n int) { n = tn n = bstd.MarshalByte(n, b, child2.Age) - n = bstd.MarshalString(n, b, child2.Name) n = child2.Parents.MarshalPlain(n, b) return n } // Unmarshal - Child2 func (child2 *Child2) Unmarshal(b []byte) (err error) { - _, err = child2.unmarshal(0, b, []uint16{}, 0) + _, err = child2.NestedUnmarshal(0, b, []uint16{}, 0) return } // Nested Unmarshal - Child2 -func (child2 *Child2) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { +func (child2 *Child2) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { var ok bool if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { if err == bgenimpl.ErrEof { @@ -225,18 +221,7 @@ func (child2 *Child2) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, return } } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, child2RIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, child2.Name, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, err = child2.Parents.unmarshal(n, b, child2RIds, 3); err != nil { + if n, err = child2.Parents.NestedUnmarshal(n, b, child2RIds, 3); err != nil { return } n += 2 @@ -249,9 +234,6 @@ func (child2 *Child2) UnmarshalPlain(tn int, b []byte) (n int, err error) { if n, child2.Age, err = bstd.UnmarshalByte(n, b); err != nil { return } - if n, child2.Name, err = bstd.UnmarshalString(n, b); err != nil { - return - } if n, err = child2.Parents.UnmarshalPlain(n, b); err != nil { return } @@ -269,11 +251,11 @@ var parents2RIds = []uint16{} // Size - Parents2 func (parents2 *Parents2) Size() int { - return parents2.size(0) + return parents2.NestedSize(0) } // Nested Size - Parents2 -func (parents2 *Parents2) size(id uint16) (s int) { +func (parents2 *Parents2) NestedSize(id uint16) (s int) { s += bstd.SizeString(parents2.Mother) + 2 s += bstd.SizeString(parents2.Father) + 2 @@ -294,11 +276,11 @@ func (parents2 *Parents2) SizePlain() (s int) { // Marshal - Parents2 func (parents2 *Parents2) Marshal(b []byte) { - parents2.marshal(0, b, 0) + parents2.NestedMarshal(0, b, 0) } // Nested Marshal - Parents2 -func (parents2 *Parents2) marshal(tn int, b []byte, id uint16) (n int) { +func (parents2 *Parents2) NestedMarshal(tn int, b []byte, id uint16) (n int) { n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 1) n = bstd.MarshalString(n, b, parents2.Mother) @@ -321,12 +303,12 @@ func (parents2 *Parents2) MarshalPlain(tn int, b []byte) (n int) { // Unmarshal - Parents2 func (parents2 *Parents2) Unmarshal(b []byte) (err error) { - _, err = parents2.unmarshal(0, b, []uint16{}, 0) + _, err = parents2.NestedUnmarshal(0, b, []uint16{}, 0) return } // Nested Unmarshal - Parents2 -func (parents2 *Parents2) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { +func (parents2 *Parents2) NestedUnmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { var ok bool if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { if err == bgenimpl.ErrEof { diff --git a/testing/person/person_test.go b/testing/person/person_test.go index bb08c7a..f07d5a8 100644 --- a/testing/person/person_test.go +++ b/testing/person/person_test.go @@ -1,385 +1,114 @@ -// Code generated by bencgen go. DO NOT EDIT. -// source: ../schemas/person.benc +//go:generate bencgen --in ../schemas/person.benc,../schemas/person2.benc --out ./ --file ... --lang go package person -import ( - "github.com/deneonet/benc/std" - "github.com/deneonet/benc/impl/gen" -) - -// Struct - Person -type Person struct { - Age byte - Name string - Parents Parents - Child Child -} - -// Reserved Ids - Person -var personRIds = []uint16{} - -// Size - Person -func (person *Person) Size() int { - return person.size(0) -} - -// Nested Size - Person -func (person *Person) size(id uint16) (s int) { - s += bstd.SizeByte() + 2 - s += bstd.SizeString(person.Name) + 2 - s += person.Parents.size(3) - s += person.Child.size(4) - - if id > 255 { - s += 5 - return - } - s += 4 - return -} - -// SizePlain - Person -func (person *Person) SizePlain() (s int) { - s += bstd.SizeByte() - s += bstd.SizeString(person.Name) - s += person.Parents.SizePlain() - s += person.Child.SizePlain() - return -} - -// Marshal - Person -func (person *Person) Marshal(b []byte) { - person.marshal(0, b, 0) -} - -// Nested Marshal - Person -func (person *Person) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed8, 1) - n = bstd.MarshalByte(n, b, person.Age) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalString(n, b, person.Name) - n = person.Parents.marshal(n, b, 3) - n = person.Child.marshal(n, b, 4) - - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} - -// MarshalPlain - Person -func (person *Person) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalByte(n, b, person.Age) - n = bstd.MarshalString(n, b, person.Name) - n = person.Parents.MarshalPlain(n, b) - n = person.Child.MarshalPlain(n, b) - return n -} - -// Unmarshal - Person -func (person *Person) Unmarshal(b []byte) (err error) { - _, err = person.unmarshal(0, b, []uint16{}, 0) - return +import "testing" + +// Forward compatibility +func TestPersonToPerson2(t *testing.T) { + originalPerson := Person{ + Age: 30, + Name: "John Doe", + Parents: Parents{ + Mother: "Jane Doe", + Father: "John Smith", + }, + Child: Child{ + Age: 10, + Name: "Junior Doe", + Parents: Parents{ + Mother: "Jane Doe", + Father: "John Doe", + }, + }, + } + + expectedPerson2 := Person2{ + Age: 30, + Name: "John Doe", + Child: Child2{ + Age: 10, + Parents: Parents2{ + Mother: "Jane Doe", + Father: "John Doe", + }, + }, + } + + buf := make([]byte, originalPerson.Size()) + originalPerson.Marshal(buf) + + var deserPerson2 Person2 + err := deserPerson2.Unmarshal(buf) + if err != nil { + t.Fatal(err) + } + + if deserPerson2.Age != expectedPerson2.Age { + t.Errorf("Expected Age %d, got %d", expectedPerson2.Age, deserPerson2.Age) + } + if deserPerson2.Name != expectedPerson2.Name { + t.Errorf("Expected Name %s, got %s", expectedPerson2.Name, deserPerson2.Name) + } + if deserPerson2.Child.Age != expectedPerson2.Child.Age { + t.Errorf("Expected Child Age %d, got %d", expectedPerson2.Child.Age, deserPerson2.Child.Age) + } + if deserPerson2.Child.Parents.Mother != expectedPerson2.Child.Parents.Mother { + t.Errorf("Expected Child's Mother %s, got %s", expectedPerson2.Child.Parents.Mother, deserPerson2.Child.Parents.Mother) + } + if deserPerson2.Child.Parents.Father != expectedPerson2.Child.Parents.Father { + t.Errorf("Expected Child's Father %s, got %s", expectedPerson2.Child.Parents.Father, deserPerson2.Child.Parents.Father) + } +} + +// Backward compatibility +func TestPerson2ToPerson(t *testing.T) { + originalPerson2 := Person2{ + Age: 30, + Name: "John Doe", + Child: Child2{ + Age: 10, + Parents: Parents2{ + Mother: "Jane Doe", + Father: "John Doe", + }, + }, + } + + expectedPerson := Person{ + Age: 30, + Name: "John Doe", + Child: Child{ + Age: 10, + Parents: Parents{ + Mother: "Jane Doe", + Father: "John Doe", + }, + }, + } + + buf := make([]byte, originalPerson2.Size()) + originalPerson2.Marshal(buf) + + var deserPerson Person + err := deserPerson.Unmarshal(buf) + if err != nil { + t.Fatal(err) + } + + if deserPerson.Age != expectedPerson.Age { + t.Errorf("Expected Age %d, got %d", expectedPerson.Age, deserPerson.Age) + } + if deserPerson.Name != expectedPerson.Name { + t.Errorf("Expected Name %s, got %s", expectedPerson.Name, deserPerson.Name) + } + if deserPerson.Child.Age != expectedPerson.Child.Age { + t.Errorf("Expected Child Age %d, got %d", expectedPerson.Child.Age, deserPerson.Child.Age) + } + if deserPerson.Child.Parents.Mother != expectedPerson.Child.Parents.Mother { + t.Errorf("Expected Child's Mother %s, got %s", expectedPerson.Child.Parents.Mother, deserPerson.Child.Parents.Mother) + } + if deserPerson.Child.Parents.Father != expectedPerson.Child.Parents.Father { + t.Errorf("Expected Child's Father %s, got %s", expectedPerson.Child.Parents.Father, deserPerson.Child.Parents.Father) + } } - -// Nested Unmarshal - Person -func (person *Person) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, personRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, person.Age, err = bstd.UnmarshalByte(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, personRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, person.Name, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, err = person.Parents.unmarshal(n, b, personRIds, 3); err != nil { - return - } - if n, err = person.Child.unmarshal(n, b, personRIds, 4); err != nil { - return - } - n += 2 - return -} - -// UnmarshalPlain - Person -func (person *Person) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, person.Age, err = bstd.UnmarshalByte(n, b); err != nil { - return - } - if n, person.Name, err = bstd.UnmarshalString(n, b); err != nil { - return - } - if n, err = person.Parents.UnmarshalPlain(n, b); err != nil { - return - } - if n, err = person.Child.UnmarshalPlain(n, b); err != nil { - return - } - return -} - -// Struct - Child -type Child struct { - Age byte - Name string - Parents Parents -} - -// Reserved Ids - Child -var childRIds = []uint16{} - -// Size - Child -func (child *Child) Size() int { - return child.size(0) -} - -// Nested Size - Child -func (child *Child) size(id uint16) (s int) { - s += bstd.SizeByte() + 2 - s += bstd.SizeString(child.Name) + 2 - s += child.Parents.size(3) - - if id > 255 { - s += 5 - return - } - s += 4 - return -} - -// SizePlain - Child -func (child *Child) SizePlain() (s int) { - s += bstd.SizeByte() - s += bstd.SizeString(child.Name) - s += child.Parents.SizePlain() - return -} - -// Marshal - Child -func (child *Child) Marshal(b []byte) { - child.marshal(0, b, 0) -} - -// Nested Marshal - Child -func (child *Child) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Fixed8, 1) - n = bstd.MarshalByte(n, b, child.Age) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalString(n, b, child.Name) - n = child.Parents.marshal(n, b, 3) - - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} - -// MarshalPlain - Child -func (child *Child) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalByte(n, b, child.Age) - n = bstd.MarshalString(n, b, child.Name) - n = child.Parents.MarshalPlain(n, b) - return n -} - -// Unmarshal - Child -func (child *Child) Unmarshal(b []byte) (err error) { - _, err = child.unmarshal(0, b, []uint16{}, 0) - return -} - -// Nested Unmarshal - Child -func (child *Child) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, childRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, child.Age, err = bstd.UnmarshalByte(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, childRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, child.Name, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, err = child.Parents.unmarshal(n, b, childRIds, 3); err != nil { - return - } - n += 2 - return -} - -// UnmarshalPlain - Child -func (child *Child) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, child.Age, err = bstd.UnmarshalByte(n, b); err != nil { - return - } - if n, child.Name, err = bstd.UnmarshalString(n, b); err != nil { - return - } - if n, err = child.Parents.UnmarshalPlain(n, b); err != nil { - return - } - return -} - -// Struct - Parents -type Parents struct { - Mother string - Father string -} - -// Reserved Ids - Parents -var parentsRIds = []uint16{} - -// Size - Parents -func (parents *Parents) Size() int { - return parents.size(0) -} - -// Nested Size - Parents -func (parents *Parents) size(id uint16) (s int) { - s += bstd.SizeString(parents.Mother) + 2 - s += bstd.SizeString(parents.Father) + 2 - - if id > 255 { - s += 5 - return - } - s += 4 - return -} - -// SizePlain - Parents -func (parents *Parents) SizePlain() (s int) { - s += bstd.SizeString(parents.Mother) - s += bstd.SizeString(parents.Father) - return -} - -// Marshal - Parents -func (parents *Parents) Marshal(b []byte) { - parents.marshal(0, b, 0) -} - -// Nested Marshal - Parents -func (parents *Parents) marshal(tn int, b []byte, id uint16) (n int) { - n = bgenimpl.MarshalTag(tn, b, bgenimpl.Container, id) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 1) - n = bstd.MarshalString(n, b, parents.Mother) - n = bgenimpl.MarshalTag(n, b, bgenimpl.Bytes, 2) - n = bstd.MarshalString(n, b, parents.Father) - - n += 2 - b[n-2] = 1 - b[n-1] = 1 - return -} - -// MarshalPlain - Parents -func (parents *Parents) MarshalPlain(tn int, b []byte) (n int) { - n = tn - n = bstd.MarshalString(n, b, parents.Mother) - n = bstd.MarshalString(n, b, parents.Father) - return n -} - -// Unmarshal - Parents -func (parents *Parents) Unmarshal(b []byte) (err error) { - _, err = parents.unmarshal(0, b, []uint16{}, 0) - return -} - -// Nested Unmarshal - Parents -func (parents *Parents) unmarshal(tn int, b []byte, r []uint16, id uint16) (n int, err error) { - var ok bool - if n, ok, err = bgenimpl.HandleCompatibility(tn, b, r, id); !ok { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, parentsRIds, 1); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, parents.Mother, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - if n, ok, err = bgenimpl.HandleCompatibility(n, b, parentsRIds, 2); err != nil { - if err == bgenimpl.ErrEof { - return n, nil - } - return - } - if ok { - if n, parents.Father, err = bstd.UnmarshalString(n, b); err != nil { - return - } - } - n += 2 - return -} - -// UnmarshalPlain - Parents -func (parents *Parents) UnmarshalPlain(tn int, b []byte) (n int, err error) { - n = tn - if n, parents.Mother, err = bstd.UnmarshalString(n, b); err != nil { - return - } - if n, parents.Father, err = bstd.UnmarshalString(n, b); err != nil { - return - } - return -} - diff --git a/testing/schemas/complex_data.benc b/testing/schemas/complex_data.benc index 02a556a..1e88de4 100644 --- a/testing/schemas/complex_data.benc +++ b/testing/schemas/complex_data.benc @@ -1,4 +1,6 @@ -header complex_data; +define complex_data; + +var go_package = "github.com/deneonet/benc/testing/complex_data"; ctr ComplexData { int id = 1; @@ -30,4 +32,4 @@ ctr SubComplexData { } # DO NOT EDIT. -# [meta_s] eyJtc2dzIjp7IkNvbXBsZXhEYXRhIjp7InJJZHMiOm51bGwsImZpZWxkcyI6eyIxIjp7IklkIjoxLCJOYW1lIjoiaWQiLCJUeXBlIjp7IlRva2VuVHlwZSI6OSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiSWQiOjIsIk5hbWUiOiJ0aXRsZSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxNSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjMiOnsiSWQiOjMsIk5hbWUiOiJpdGVtcyIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsIkN0ck5hbWUiOiJTdWJJdGVtIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfSwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6dHJ1ZSwiSXNNYXAiOmZhbHNlfX0sIjQiOnsiSWQiOjQsIk5hbWUiOiJtZXRhZGF0YSIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjp7IlRva2VuVHlwZSI6MTUsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjcsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sIkN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6dHJ1ZX19LCI1Ijp7IklkIjo1LCJOYW1lIjoic3ViX2RhdGEiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJDdHJOYW1lIjoiU3ViQ29tcGxleERhdGEiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiNiI6eyJJZCI6NiwiTmFtZSI6ImxhcmdlX2JpbmFyeV9kYXRhIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjE0LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsIkN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5Ijp0cnVlLCJJc01hcCI6ZmFsc2V9fSwiNyI6eyJJZCI6NywiTmFtZSI6Imh1Z2VfbGlzdCIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOnsiVG9rZW5UeXBlIjo2LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsIkN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5Ijp0cnVlLCJJc01hcCI6ZmFsc2V9fX19LCJTdWJDb21wbGV4RGF0YSI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJJZCI6MSwiTmFtZSI6InN1Yl9pZCIsIlR5cGUiOnsiVG9rZW5UeXBlIjo3LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsIkN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJJZCI6MiwiTmFtZSI6InN1Yl90aXRsZSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxNSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjMiOnsiSWQiOjMsIk5hbWUiOiJzdWJfYmluYXJ5X2RhdGEiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjp7IlRva2VuVHlwZSI6MTQsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sIkN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOnRydWUsIklzTWFwIjpmYWxzZX19LCI0Ijp7IklkIjo0LCJOYW1lIjoic3ViX2l0ZW1zIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IlN1Ykl0ZW0iLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5Ijp0cnVlLCJJc01hcCI6ZmFsc2V9fSwiNSI6eyJJZCI6NSwiTmFtZSI6InN1Yl9tZXRhZGF0YSIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjp7IlRva2VuVHlwZSI6MTUsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjE1LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsIkN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOnRydWV9fX19LCJTdWJJdGVtIjp7InJJZHMiOm51bGwsImZpZWxkcyI6eyIxIjp7IklkIjoxLCJOYW1lIjoic3ViX2lkIiwiVHlwZSI6eyJUb2tlblR5cGUiOjcsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIyIjp7IklkIjoyLCJOYW1lIjoiZGVzY3JpcHRpb24iLCJUeXBlIjp7IlRva2VuVHlwZSI6MTUsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIzIjp7IklkIjozLCJOYW1lIjoic3ViX2l0ZW1zIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IlN1YlN1Ykl0ZW0iLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5Ijp0cnVlLCJJc01hcCI6ZmFsc2V9fX19LCJTdWJTdWJJdGVtIjp7InJJZHMiOm51bGwsImZpZWxkcyI6eyIxIjp7IklkIjoxLCJOYW1lIjoic3ViX3N1Yl9pZCIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxNSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJDdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiSWQiOjIsIk5hbWUiOiJzdWJfc3ViX2RhdGEiLCJUeXBlIjp7IlRva2VuVHlwZSI6MTQsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiQ3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX19fQ== [meta_e] \ No newline at end of file +# [meta_s] eyJtc2dzIjp7IkNvbXBsZXhEYXRhIjp7InJJZHMiOm51bGwsImZpZWxkcyI6eyIxIjp7ImlkIjoxLCJOYW1lIjoiaWQiLCJUeXBlIjp7IlRva2VuVHlwZSI6MTQsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIyIjp7ImlkIjoyLCJOYW1lIjoidGl0bGUiLCJUeXBlIjp7IlRva2VuVHlwZSI6MjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIzIjp7ImlkIjozLCJOYW1lIjoiaXRlbXMiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiU3ViSXRlbSIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOnRydWUsIklzTWFwIjpmYWxzZX19LCI0Ijp7ImlkIjo0LCJOYW1lIjoibWV0YWRhdGEiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6eyJUb2tlblR5cGUiOjIwLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJDaGlsZFR5cGUiOnsiVG9rZW5UeXBlIjoxMiwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfSwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjp0cnVlfX0sIjUiOnsiaWQiOjUsIk5hbWUiOiJzdWJfZGF0YSIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiJTdWJDb21wbGV4RGF0YSIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCI2Ijp7ImlkIjo2LCJOYW1lIjoibGFyZ2VfYmluYXJ5X2RhdGEiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjp7IlRva2VuVHlwZSI6MTksIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOnRydWUsIklzTWFwIjpmYWxzZX19LCI3Ijp7ImlkIjo3LCJOYW1lIjoiaHVnZV9saXN0IiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjExLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5Ijp0cnVlLCJJc01hcCI6ZmFsc2V9fX19LCJTdWJDb21wbGV4RGF0YSI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJpZCI6MSwiTmFtZSI6InN1Yl9pZCIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxMiwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiaWQiOjIsIk5hbWUiOiJzdWJfdGl0bGUiLCJUeXBlIjp7IlRva2VuVHlwZSI6MjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIzIjp7ImlkIjozLCJOYW1lIjoic3ViX2JpbmFyeV9kYXRhIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjE5LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5Ijp0cnVlLCJJc01hcCI6ZmFsc2V9fSwiNCI6eyJpZCI6NCwiTmFtZSI6InN1Yl9pdGVtcyIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiJTdWJJdGVtIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfSwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6dHJ1ZSwiSXNNYXAiOmZhbHNlfX0sIjUiOnsiaWQiOjUsIk5hbWUiOiJzdWJfbWV0YWRhdGEiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6eyJUb2tlblR5cGUiOjIwLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJDaGlsZFR5cGUiOnsiVG9rZW5UeXBlIjoyMCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfSwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjp0cnVlfX19fSwiU3ViSXRlbSI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJpZCI6MSwiTmFtZSI6InN1Yl9pZCIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxMiwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiaWQiOjIsIk5hbWUiOiJkZXNjcmlwdGlvbiIsIlR5cGUiOnsiVG9rZW5UeXBlIjoyMCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjMiOnsiaWQiOjMsIk5hbWUiOiJzdWJfaXRlbXMiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiU3ViU3ViSXRlbSIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOnRydWUsIklzTWFwIjpmYWxzZX19fX0sIlN1YlN1Ykl0ZW0iOnsicklkcyI6bnVsbCwiZmllbGRzIjp7IjEiOnsiaWQiOjEsIk5hbWUiOiJzdWJfc3ViX2lkIiwiVHlwZSI6eyJUb2tlblR5cGUiOjIwLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJpZCI6MiwiTmFtZSI6InN1Yl9zdWJfZGF0YSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxOSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX19fX19 [meta_e] \ No newline at end of file diff --git a/testing/schemas/others.benc b/testing/schemas/others.benc index ece4988..2a6c1d1 100644 --- a/testing/schemas/others.benc +++ b/testing/schemas/others.benc @@ -1,4 +1,9 @@ -header others; +define others; + +use "person.benc"; +use "person2.benc"; + +var go_package = "github.com/deneonet/benc/testing/others"; enum ExampleEnum { One, @@ -13,17 +18,21 @@ enum ExampleEnum2 { } ctr OthersTest { - uint64 ui64 = 1; - []uint64 ui64Arr = 2; - ui64Map = 3; + uint ui = 1; + + uint64 ui64 = 2; + []uint64 ui64Arr = 3; + ui64Map = 4; + + uint32 ui32 = 5; + uint16 ui16 = 6; - uint32 ui32 = 4; - uint16 ui16 = 5; - uint ui = 7; + ExampleEnum exampleEnum = 7; + ExampleEnum2 exampleEnum2 = 8; - ExampleEnum exampleEnum = 8; - ExampleEnum2 exampleEnum2 = 9; + person.Person person = 9; + person.2.test.defines.Person2 person2 = 10; } # DO NOT EDIT. -# [meta_s] eyJtc2dzIjp7Ik90aGVyc1Rlc3QiOnsicklkcyI6bnVsbCwiZmllbGRzIjp7IjEiOnsiSWQiOjEsIk5hbWUiOiJ1aTY0IiwiVHlwZSI6eyJUb2tlblR5cGUiOjEwLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJJZCI6MiwiTmFtZSI6InVpNjRBcnIiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjp7IlRva2VuVHlwZSI6MTAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOnRydWUsIklzTWFwIjpmYWxzZX19LCIzIjp7IklkIjozLCJOYW1lIjoidWk2NE1hcCIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjp7IlRva2VuVHlwZSI6MTAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sIkNoaWxkVHlwZSI6eyJUb2tlblR5cGUiOjExLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9LCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOnRydWV9fSwiNCI6eyJJZCI6NCwiTmFtZSI6InVpMzIiLCJUeXBlIjp7IlRva2VuVHlwZSI6MTEsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCI1Ijp7IklkIjo1LCJOYW1lIjoidWkxNiIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxMiwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjciOnsiSWQiOjcsIk5hbWUiOiJ1aSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxMywiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjgiOnsiSWQiOjgsIk5hbWUiOiJleGFtcGxlRW51bSIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiJFeGFtcGxlRW51bSIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCI5Ijp7IklkIjo5LCJOYW1lIjoiZXhhbXBsZUVudW0yIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IkV4YW1wbGVFbnVtMiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX19fQ== [meta_e] \ No newline at end of file +# [meta_s] eyJtc2dzIjp7Ik90aGVyc1Rlc3QiOnsicklkcyI6bnVsbCwiZmllbGRzIjp7IjEiOnsiaWQiOjEsIk5hbWUiOiJ1aSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxOCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjEwIjp7ImlkIjoxMCwiTmFtZSI6InBlcnNvbjIiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoicGVyc29uLlBlcnNvbjIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJpZCI6MiwiTmFtZSI6InVpNjQiLCJUeXBlIjp7IlRva2VuVHlwZSI6MTUsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIzIjp7ImlkIjozLCJOYW1lIjoidWk2NEFyciIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOnsiVG9rZW5UeXBlIjoxNSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfSwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6dHJ1ZSwiSXNNYXAiOmZhbHNlfX0sIjQiOnsiaWQiOjQsIk5hbWUiOiJ1aTY0TWFwIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOnsiVG9rZW5UeXBlIjoxNSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfSwiQ2hpbGRUeXBlIjp7IlRva2VuVHlwZSI6MTYsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX0sImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6dHJ1ZX19LCI1Ijp7ImlkIjo1LCJOYW1lIjoidWkzMiIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxNiwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjYiOnsiaWQiOjYsIk5hbWUiOiJ1aTE2IiwiVHlwZSI6eyJUb2tlblR5cGUiOjE3LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiNyI6eyJpZCI6NywiTmFtZSI6ImV4YW1wbGVFbnVtIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IkV4YW1wbGVFbnVtIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjgiOnsiaWQiOjgsIk5hbWUiOiJleGFtcGxlRW51bTIiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiRXhhbXBsZUVudW0yIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjkiOnsiaWQiOjksIk5hbWUiOiJwZXJzb24iLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoicGVyc29uLlBlcnNvbiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX19fQ== [meta_e] \ No newline at end of file diff --git a/testing/schemas/person.benc b/testing/schemas/person.benc index 3cc397f..d375410 100644 --- a/testing/schemas/person.benc +++ b/testing/schemas/person.benc @@ -1,4 +1,6 @@ -header person; +define person; + +var go_package = "github.com/deneonet/benc/testing/person"; ctr Person { byte age = 1; @@ -19,4 +21,4 @@ ctr Parents { } # DO NOT EDIT. -# [meta_s] eyJtc2dzIjp7IkNoaWxkIjp7InJJZHMiOm51bGwsImZpZWxkcyI6eyIxIjp7IklkIjoxLCJOYW1lIjoiYWdlIiwiVHlwZSI6eyJUb2tlblR5cGUiOjE5LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJJZCI6MiwiTmFtZSI6Im5hbWUiLCJUeXBlIjp7IlRva2VuVHlwZSI6MTUsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIzIjp7IklkIjozLCJOYW1lIjoicGFyZW50cyIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiJQYXJlbnRzIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX19fSwiUGFyZW50cyI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJJZCI6MSwiTmFtZSI6Im1vdGhlciIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxNSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiSWQiOjIsIk5hbWUiOiJmYXRoZXIiLCJUeXBlIjp7IlRva2VuVHlwZSI6MTUsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX0sIlBlcnNvbiI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJJZCI6MSwiTmFtZSI6ImFnZSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxOSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiSWQiOjIsIk5hbWUiOiJuYW1lIiwiVHlwZSI6eyJUb2tlblR5cGUiOjE1LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMyI6eyJJZCI6MywiTmFtZSI6InBhcmVudHMiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiUGFyZW50cyIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCI0Ijp7IklkIjo0LCJOYW1lIjoiY2hpbGQiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiQ2hpbGQiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fX19fX0= [meta_e] \ No newline at end of file +# [meta_s] eyJtc2dzIjp7IkNoaWxkIjp7InJJZHMiOm51bGwsImZpZWxkcyI6eyIxIjp7ImlkIjoxLCJOYW1lIjoiYWdlIiwiVHlwZSI6eyJUb2tlblR5cGUiOjI0LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJpZCI6MiwiTmFtZSI6Im5hbWUiLCJUeXBlIjp7IlRva2VuVHlwZSI6MjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIzIjp7ImlkIjozLCJOYW1lIjoicGFyZW50cyIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiJQYXJlbnRzIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX19fSwiUGFyZW50cyI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJpZCI6MSwiTmFtZSI6Im1vdGhlciIsIlR5cGUiOnsiVG9rZW5UeXBlIjoyMCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiaWQiOjIsIk5hbWUiOiJmYXRoZXIiLCJUeXBlIjp7IlRva2VuVHlwZSI6MjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX0sIlBlcnNvbiI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJpZCI6MSwiTmFtZSI6ImFnZSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoyNCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiaWQiOjIsIk5hbWUiOiJuYW1lIiwiVHlwZSI6eyJUb2tlblR5cGUiOjIwLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMyI6eyJpZCI6MywiTmFtZSI6InBhcmVudHMiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiUGFyZW50cyIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCI0Ijp7ImlkIjo0LCJOYW1lIjoiY2hpbGQiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiQ2hpbGQiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fX19fX0= [meta_e] \ No newline at end of file diff --git a/testing/schemas/person2.benc b/testing/schemas/person2.benc index 0069aa0..b9d878b 100644 --- a/testing/schemas/person2.benc +++ b/testing/schemas/person2.benc @@ -1,4 +1,6 @@ -header person; +define person.2.test.defines; + +var go_package = "github.com/deneonet/benc/testing/person"; ctr Person2 { reserved 3; @@ -9,8 +11,9 @@ ctr Person2 { } ctr Child2 { + reserved 2; + byte age = 1; - string name = 2; Parents2 parents = 3; } @@ -20,4 +23,4 @@ ctr Parents2 { } # DO NOT EDIT. -# [meta_s] eyJtc2dzIjp7IkNoaWxkMiI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJJZCI6MSwiTmFtZSI6ImFnZSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxOSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiSWQiOjIsIk5hbWUiOiJuYW1lIiwiVHlwZSI6eyJUb2tlblR5cGUiOjE1LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMyI6eyJJZCI6MywiTmFtZSI6InBhcmVudHMiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiUGFyZW50czIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fX19LCJQYXJlbnRzMiI6eyJySWRzIjpudWxsLCJmaWVsZHMiOnsiMSI6eyJJZCI6MSwiTmFtZSI6Im1vdGhlciIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxNSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiSWQiOjIsIk5hbWUiOiJmYXRoZXIiLCJUeXBlIjp7IlRva2VuVHlwZSI6MTUsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX0sIlBlcnNvbjIiOnsicklkcyI6WzNdLCJmaWVsZHMiOnsiMSI6eyJJZCI6MSwiTmFtZSI6ImFnZSIsIlR5cGUiOnsiVG9rZW5UeXBlIjoxOSwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX0sIjIiOnsiSWQiOjIsIk5hbWUiOiJuYW1lIiwiVHlwZSI6eyJUb2tlblR5cGUiOjE1LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiNCI6eyJJZCI6NCwiTmFtZSI6ImNoaWxkIiwiVHlwZSI6eyJUb2tlblR5cGUiOjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IkNoaWxkMiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX19fQ== [meta_e] \ No newline at end of file +# [meta_s] eyJtc2dzIjp7IkNoaWxkMiI6eyJySWRzIjpbMl0sImZpZWxkcyI6eyIxIjp7ImlkIjoxLCJOYW1lIjoiYWdlIiwiVHlwZSI6eyJUb2tlblR5cGUiOjI0LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJpZCI6MiwiTmFtZSI6Im5hbWUiLCJUeXBlIjp7IlRva2VuVHlwZSI6MjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCIzIjp7ImlkIjozLCJOYW1lIjoicGFyZW50cyIsIlR5cGUiOnsiVG9rZW5UeXBlIjowLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiJQYXJlbnRzMiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19fX0sIlBhcmVudHMyIjp7InJJZHMiOm51bGwsImZpZWxkcyI6eyIxIjp7ImlkIjoxLCJOYW1lIjoibW90aGVyIiwiVHlwZSI6eyJUb2tlblR5cGUiOjIwLCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJpZCI6MiwiTmFtZSI6ImZhdGhlciIsIlR5cGUiOnsiVG9rZW5UeXBlIjoyMCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX19fSwiUGVyc29uMiI6eyJySWRzIjpbM10sImZpZWxkcyI6eyIxIjp7ImlkIjoxLCJOYW1lIjoiYWdlIiwiVHlwZSI6eyJUb2tlblR5cGUiOjI0LCJNYXBLZXlUeXBlIjpudWxsLCJDaGlsZFR5cGUiOm51bGwsImN0ck5hbWUiOiIiLCJJc1Vuc2FmZSI6ZmFsc2UsIklzQXJyYXkiOmZhbHNlLCJJc01hcCI6ZmFsc2V9fSwiMiI6eyJpZCI6MiwiTmFtZSI6Im5hbWUiLCJUeXBlIjp7IlRva2VuVHlwZSI6MjAsIk1hcEtleVR5cGUiOm51bGwsIkNoaWxkVHlwZSI6bnVsbCwiY3RyTmFtZSI6IiIsIklzVW5zYWZlIjpmYWxzZSwiSXNBcnJheSI6ZmFsc2UsIklzTWFwIjpmYWxzZX19LCI0Ijp7ImlkIjo0LCJOYW1lIjoiY2hpbGQiLCJUeXBlIjp7IlRva2VuVHlwZSI6MCwiTWFwS2V5VHlwZSI6bnVsbCwiQ2hpbGRUeXBlIjpudWxsLCJjdHJOYW1lIjoiQ2hpbGQyIiwiSXNVbnNhZmUiOmZhbHNlLCJJc0FycmF5IjpmYWxzZSwiSXNNYXAiOmZhbHNlfX19fX19 [meta_e] \ No newline at end of file