Skip to content

Commit

Permalink
[Go] SBE implementation in Go using flyweights real-logic#765
Browse files Browse the repository at this point in the history
To generate flyweights instead of structs, set the following flag:

```
sbe.go.generate.generate.flyweights=true
```
  • Loading branch information
ethanf committed Aug 8, 2023
1 parent 384e021 commit bf3c616
Show file tree
Hide file tree
Showing 65 changed files with 5,617 additions and 58 deletions.
75 changes: 50 additions & 25 deletions .gitignore
Expand Up @@ -62,31 +62,56 @@ cppbuild/Win32

# golang
gocode/pkg
gocode/src/baseline/*.go
!gocode/src/baseline/*_test.go
gocode/src/baseline-bigendian/*.go
!gocode/src/baseline-bigendian/*_test.go
gocode/src/composite/*.go
!gocode/src/composite/*_test.go
gocode/src/composite_elements/*.go
!gocode/src/composite_elements/*_test.go
gocode/src/since-deprecated/*.go
!gocode/src/since-deprecated/*_test.go
gocode/src/group_with_data*/*.go
!gocode/src/group_with_data*/*_test.go
gocode/src/mktdata/*.go
!gocode/src/mktdata/*_test.go
gocode/src/simple/*.go
!gocode/src/simple/*_test.go
gocode/src/issue*/*.go
!gocode/src/issue*/*_test.go
gocode/src/*/*/*.go
!gocode/src/*/*/*_test.go
gocode/src/example-schema/example-schema*
gocode/src/example-schema/cpu.out
gocode/src/example-socket-clientserver/example-socket-clientserver
gocode/src/extension
gocode/src/extension2
gocode/src/struct/baseline/*.go
!gocode/src/struct/baseline/*_test.go
gocode/src/struct/baseline-bigendian/*.go
!gocode/src/struct/baseline-bigendian/*_test.go
gocode/src/struct/composite/*.go
!gocode/src/struct/composite/*_test.go
gocode/src/struct/composite_elements/*.go
!gocode/src/struct/composite_elements/*_test.go
gocode/src/struct/since-deprecated/*.go
!gocode/src/struct/since-deprecated/*_test.go
gocode/src/struct/group_with_data*/*.go
!gocode/src/struct/group_with_data*/*_test.go
gocode/src/struct/mktdata/*.go
!gocode/src/struct/mktdata/*_test.go
gocode/src/struct/simple/*.go
!gocode/src/struct/simple/*_test.go
gocode/src/struct/issue*/*.go
!gocode/src/struct/issue*/*_test.go
gocode/src/struct/*/*/*.go
!gocode/src/struct/*/*/*_test.go
gocode/src/struct/example-schema/example-schema*
gocode/src/struct/example-schema/cpu.out
gocode/src/struct/example-socket-clientserver/example-socket-clientserver
gocode/src/struct/extension
gocode/src/struct/extension2
gocode/src/flyweight/baseline/*.go
!gocode/src/flyweight/baseline/*_test.go
gocode/src/flyweight/baseline-bigendian/*.go
!gocode/src/flyweight/baseline-bigendian/*_test.go
gocode/src/flyweight/composite/*.go
!gocode/src/flyweight/composite/*_test.go
gocode/src/flyweight/composite_elements/*.go
!gocode/src/flyweight/composite_elements/*_test.go
gocode/src/flyweight/since-deprecated/*.go
!gocode/src/flyweight/since-deprecated/*_test.go
gocode/src/flyweight/group_with_data*/*.go
!gocode/src/flyweight/group_with_data*/*_test.go
gocode/src/flyweight/mktdata/*.go
!gocode/src/flyweight/mktdata/*_test.go
gocode/src/flyweight/simple/*.go
!gocode/src/flyweight/simple/*_test.go
gocode/src/flyweight/issue*/*.go
!gocode/src/flyweight/issue*/*_test.go
gocode/src/flyweight/*/*/*.go
!gocode/src/flyweight/*/*/*_test.go
gocode/src/flyweight/example-schema/example-schema*
gocode/src/flyweight/example-schema/cpu.out
gocode/src/flyweight/example-socket-clientserver/example-socket-clientserver
gocode/src/flyweight/extension
gocode/src/flyweight/extension2

# csharp
csharp/*/bin
Expand Down
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -97,6 +97,8 @@ For convenience on Linux, a gnu Makefile is provided that runs some tests and co
$ cd gocode
# make # test, examples, bench

Go supports both generating Go structs with encode / decode methods, and flyweights like the other languages. Structs are generated by default for compatibility. Set `sbe.go.generate.generate.flyweights=true` to generate flyweights.

Users of golang generated code should see the [user
documentation](https://github.com/real-logic/simple-binary-encoding/wiki/Golang-User-Guide).

Expand Down
100 changes: 93 additions & 7 deletions build.gradle
Expand Up @@ -627,7 +627,7 @@ tasks.register('generateGolangCodecTestComposite', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src',
'sbe.output.dir': 'gocode/src/struct',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/composite-elements-schema-rc4.xml']
}
Expand All @@ -636,7 +636,7 @@ tasks.register('generateGolangCodecTestBasic', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/basic',
'sbe.output.dir': 'gocode/src/struct/basic',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/basic-types-schema.xml']
}
Expand All @@ -645,7 +645,7 @@ tasks.register('generateGolangCodecTestGroup', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/group',
'sbe.output.dir': 'gocode/src/struct/group',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/basic-group-schema.xml']
}
Expand All @@ -654,7 +654,7 @@ tasks.register('generateGolangCodecTestVarData', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/vardata',
'sbe.output.dir': 'gocode/src/struct/vardata',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/basic-variable-length-schema.xml']
}
Expand All @@ -663,7 +663,7 @@ tasks.register('generateGolangCodecsWithXIncludes', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src',
'sbe.output.dir': 'gocode/src/struct',
'sbe.target.language': 'golang',
'sbe.xinclude.aware': 'true',
'sbe.validation.xsd': validationXsdPath)
Expand All @@ -675,7 +675,87 @@ tasks.register('generateGolangCodecsWithXSD', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src',
'sbe.output.dir': 'gocode/src/struct',
'sbe.target.language': 'golang',
'sbe.xinclude.aware': 'true',
'sbe.validation.xsd': validationXsdPath)
args = ['sbe-tool/src/test/resources/group-with-data-schema.xml',
'sbe-tool/src/test/resources/FixBinary.xml',
'sbe-tool/src/test/resources/issue435.xml',
'sbe-tool/src/test/resources/issue472.xml',
'sbe-tool/src/test/resources/issue483.xml',
'sbe-tool/src/test/resources/issue488.xml',
'sbe-tool/src/test/resources/issue560.xml',
'sbe-tool/src/test/resources/issue661.xml',
'sbe-tool/src/test/resources/issue847.xml',
'sbe-tool/src/test/resources/issue848.xml',
'sbe-tool/src/test/resources/issue849.xml',
'sbe-tool/src/test/resources/since-deprecated-test-schema.xml',
'sbe-tool/src/test/resources/example-bigendian-test-schema.xml',
'gocode/resources/example-composite.xml',
'gocode/resources/group-with-data-extension-schema.xml',
'gocode/resources/simple.xml']
}

tasks.register('generateGolangFlyweightCodecTestComposite', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/flyweight',
'sbe.go.generate.generate.flyweights': 'true',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/composite-elements-schema-rc4.xml']
}

tasks.register('generateGolangFlyweightCodecTestBasic', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/flyweight/basic',
'sbe.go.generate.generate.flyweights': 'true',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/basic-types-schema.xml']
}

tasks.register('generateGolangFlyweightCodecTestGroup', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/flyweight/group',
'sbe.go.generate.generate.flyweights': 'true',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/basic-group-schema.xml']
}

tasks.register('generateGolangFlyweightCodecTestVarData', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/flyweight/vardata',
'sbe.go.generate.generate.flyweights': 'true',
'sbe.target.language': 'golang')
args = ['sbe-tool/src/test/resources/basic-variable-length-schema.xml']
}

tasks.register('generateGolangFlyweightCodecsWithXIncludes', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/flyweight',
'sbe.go.generate.generate.flyweights': 'true',
'sbe.target.language': 'golang',
'sbe.xinclude.aware': 'true',
'sbe.validation.xsd': validationXsdPath)
args = ['sbe-samples/src/main/resources/example-schema.xml',
'sbe-samples/src/main/resources/example-extension-schema.xml']
}

tasks.register('generateGolangFlyweightCodecsWithXSD', JavaExec) {
mainClass.set('uk.co.real_logic.sbe.SbeTool')
classpath = project(':sbe-tool').sourceSets.main.runtimeClasspath
systemProperties(
'sbe.output.dir': 'gocode/src/flyweight',
'sbe.go.generate.generate.flyweights': 'true',
'sbe.target.language': 'golang',
'sbe.xinclude.aware': 'true',
'sbe.validation.xsd': validationXsdPath)
Expand Down Expand Up @@ -704,7 +784,13 @@ tasks.register('generateGolangCodecs') {
'generateGolangCodecTestBasic',
'generateGolangCodecTestComposite',
'generateGolangCodecsWithXIncludes',
'generateGolangCodecsWithXSD'
'generateGolangCodecsWithXSD',
'generateGolangFlyweightCodecTestVarData',
'generateGolangFlyweightCodecTestGroup',
'generateGolangFlyweightCodecTestBasic',
'generateGolangFlyweightCodecTestComposite',
'generateGolangFlyweightCodecsWithXIncludes',
'generateGolangFlyweightCodecsWithXSD'
}

/*
Expand Down
49 changes: 36 additions & 13 deletions gocode/Makefile
Expand Up @@ -19,68 +19,91 @@ all: example test # bench
# This target is used to build golang files using parent gradle
# script's invocation of sbe-tool in case it needs to be run again. We
# use this one output file to check that dependency as it's simple
DEP=src/simple/SbeMarshalling.go
DEP=src/struct/simple/SbeMarshalling.go
$(DEP): $(SBE_JAR)
(cd ..; ./gradlew generateGolangCodecs)
(export GOPATH=$(GOPATH) && \
cd src/simple && \
cd src/struct/simple && \
go build && \
$(SAVE_FORMAT) \
go fmt && \
go test)

# Will regenerate codecs by removing dependencies
clean:
rm -f src/*/SbeMarshalling.go src/*/*/SbeMarshalling.go
rm -f src/struct/*/SbeMarshalling.go src/struct/*/*/SbeMarshalling.go

# Example code and benchmarking
example: src/example-schema/example-schema
src/example-schema/example-schema: $(DEP)
example: src/struct/example-schema/example-schema
src/struct/example-schema/example-schema: $(DEP)
(export GOPATH=$(GOPATH) && \
cd src/example-schema && \
cd src/struct/example-schema && \
go build && \
go fmt && \
./example-schema)

bench: $(DEP)
(export GOPATH=$(GOPATH) && \
cd src/example-schema && \
cd src/struct/example-schema && \
go test --bench . -cpuprofile=cpu.out && \
go tool pprof -text example-schema.test cpu.out)

src/baseline/SbeMarshalling.go: $(DEP)
src/struct/baseline/SbeMarshalling.go: $(DEP)
$(GOPATH)/sbe-tool -d src -s $(EXAMPLES_SCHEMA)
(export GOPATH=$(GOPATH) && \
cd src/baseline && \
cd src/struct/baseline && \
go build && \
go fmt && \
go test && \
go install)

# The first set does a make install as there is a test that uses
# multiple packages and needs them in GOPATH The second set work in
# src/foo, and the third need a GOPATH addition as for Java and C++
# src/struct/foo, and the third need a GOPATH addition as for Java and C++
# they generate into the same directory but golang doesn't allow that
test: $(DEP)
(export GOPATH=$(GOPATH) && \
(for t in baseline extension; do \
export GOPATH=$(GOPATH) && \
cd $(GOPATH)/src/$$t && \
cd $(GOPATH)/src/struct/$$t && \
go build && \
go fmt && \
go test && \
go install \
;done))
(export GOPATH=$(GOPATH) && \
(for t in baseline-bigendian mktdata group_with_data group_with_data_extension composite_elements composite since-deprecated simple issue435 issue472 issue483 issue488 issue560 issue847 issue848 issue849; do \
cd $(GOPATH)/src/$$t && \
cd $(GOPATH)/src/struct/$$t && \
go build && \
go fmt && \
go test \
;done))
(for t in vardata group basic; do \
export GOPATH=$(GOPATH)/$$t && \
cd $(GOPATH)/src/$$t/'SBE tests' && \
cd $(GOPATH)/src/struct/$$t/'SBE tests' && \
go build && \
go fmt && \
go test \
;done)
(export GOPATH=$(GOPATH) && \
(for t in baseline extension; do \
export GOPATH=$(GOPATH) && \
cd $(GOPATH)/src/flyweight/$$t && \
go build && \
go fmt && \
go test && \
go install \
;done))
(export GOPATH=$(GOPATH) && \
(for t in baseline-bigendian mktdata group_with_data group_with_data_extension composite_elements composite since-deprecated simple issue435 issue472 issue483 issue488 issue560 issue847 issue848 issue849; do \
cd $(GOPATH)/src/flyweight/$$t && \
go build && \
go fmt && \
go test \
;done))
(for t in vardata group basic; do \
export GOPATH=$(GOPATH)/$$t && \
cd $(GOPATH)/src/flyweight/$$t/'SBE tests' && \
go build && \
go fmt && \
go test \
Expand Down
10 changes: 6 additions & 4 deletions gocode/README.md
Expand Up @@ -5,10 +5,13 @@ There is now a
[user guide](https://github.com/real-logic/simple-binary-encoding/wiki/Golang-User-Guide)
and this document is for development of the SBE golang generator.

Go supports both generating Go structs with encode / decode methods, and flyweights like the other languages.
Structs are generated by default for compatibility. Set `sbe.go.generate.generate.flyweights=true` to generate flyweights.

Code Layout
-----------
The Java code that performs the generation of golang code is
[here](https://github.com/real-logic/simple-binary-encoding/tree/master/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang).
[here](https://github.com/real-logic/simple-binary-encoding/tree/master/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang). There is both a struct and a flyweight generator.

Golang code used for testing resides in the top-level
[gocode directory](https://github.com/real-logic/simple-binary-encoding/tree/master/gocode).
Expand All @@ -24,11 +27,12 @@ the build environment, example and test code are structured into a top
level gocode directory hierarchy.

Code is generated into this structure with pre-existing test code in place.
There are tests for both the struct and flyweight styles of generated code.

For the example, the code is generated into a library and the matching
example code lives in it's own directory at the same level. For
example, the example-schema generates the baseline library code into
`gocode/src/baseline` and example code lives in `gocode/src/example-schema`.
`gocode/src/struct/baseline` and example code lives in `gocode/src/example-schema`.

To use this layout you should `set GOPATH=/path/to/gocode` or use the
supplied Makefile which does this for you. For the tests you will need
Expand Down Expand Up @@ -60,5 +64,3 @@ generator processes.
Roadmap
=======
* Windows developer support (currently tested on Linux/MacOS)
* Further Unicode support
* Testing/Bug fixes
7 changes: 7 additions & 0 deletions gocode/go.mod
@@ -0,0 +1,7 @@
module github.com/real-logic/simple-binary-encoding

go 1.12

require (
github.com/stretchr/testify v1.7.0
)
7 changes: 7 additions & 0 deletions gocode/go.sum
@@ -0,0 +1,7 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit bf3c616

Please sign in to comment.