Skip to content

Commit d443ff9

Browse files
committed
golang backend phase2
This release is mostly functionally complete but see gocode/README.md for next steps. Note, there are API Changes and added methods. Handle extension logic so that schemas may be extended. Implement Deprecated(). General code improvements/refactoring. Vastly improve group handling code. Add helper methods to choices. Add much more testing with bug fixes. Properly introduce raneg checking on encode/decode so we can better check for correctness. Improve the documentation/design doc. Improve the build environment (but see README.md) Add some initial benchmark cases before beginning performance work. Fix go fmt - generated code is now clean.
1 parent 11c3dda commit d443ff9

File tree

21 files changed

+1836
-536
lines changed

21 files changed

+1836
-536
lines changed

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,18 @@ gocode/src/composite/*.go
7070
!gocode/src/composite/*_test.go
7171
gocode/src/composite_elements/*.go
7272
!gocode/src/composite_elements/*_test.go
73-
gocode/src/group_with_data/*.go
74-
!gocode/src/group_with_data/*_test.go
73+
gocode/src/group_with_data*/*.go
74+
!gocode/src/group_with_data*/*_test.go
7575
gocode/src/mktdata/*.go
7676
!gocode/src/mktdata/*_test.go
7777
gocode/src/simple/*.go
7878
!gocode/src/simple/*_test.go
7979
gocode/src/*/*/*.go
8080
!gocode/src/*/*/*_test.go
81-
gocode/src/example-schema/example-schema
81+
gocode/src/example-schema/example-schema*
82+
gocode/src/example-schema/cpu.out
83+
gocode/src/extension
84+
gocode/src/extension2
8285

8386
# Mac
8487
.DS_Store

config/suppress.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
"http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
55
<suppressions>
66
<suppress files=".*generated.*" checks="."/>
7+
<suppress files="GolangGenerator.java" checks="MethodLength"/>
78
</suppressions>

gocode/Makefile

Lines changed: 87 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
11
ROOT=..
2-
SBE_TOOL_VERSION=`cat $(ROOT)/version.txt`
2+
SBE_TOOL_VERSION=$(shell cat $(ROOT)/version.txt)
33
SBE_JAR=$(ROOT)/sbe-all/build/libs/sbe-all-${SBE_TOOL_VERSION}.jar
44

5-
SCHEMA_DIR=$(ROOT)/sbe-samples/src/main/resources
6-
EXAMPLES_SCHEMA=$(SCHEMA_DIR)/example-schema.xml
7-
EXAMPLES_OUTPUT=EXAMPLES_OUTPUT
8-
95
#JAVA=/usr/lib/jvm/java-8-openjdk-amd64/bin/java
106
JAVA=java
117

128
TESTDIR=$(ROOT)/sbe-tool/src/test/golang
139

1410
JAVA_FILES="-jar ${SBE_JAR}"
1511

16-
# During development we can speed up a build by selective building and
17-
# using this but it needs periodic refresh for agrona version
18-
#JAVA_FILES="-cp ${$CP}"
19-
#CP=$(ROOT)/sbe-all/build/classes/main:$(ROOT)/sbe-all/build/resources/main:$(ROOT)/sbe-tool/build/libs/sbe-tool-$(SBE_TOOL_VERSION).jar:/home/bill/.gradle/caches/modules-2/files-2.1/org.agrona/Agrona/0.5.5/5a576d17c57c5c85b9a1ce19f030746e214e281b/Agrona-0.5.5.jar
20-
2112
# FIXME: Go doesn't like relative paths so us a gnumake extension for now
2213
GOPATH=$(realpath $(ROOT)/gocode)
2314
OUTPUTDIR=$(GOPATH)/src
15+
XMLLOCAL=$(GOPATH)/resources
2416

2517
# Local examples to get started
26-
SIMPLE=$(GOPATH)/resources/simple.xml
27-
COMPOSITE=$(GOPATH)/resources/example-composite.xml
18+
SIMPLE=$(XMLLOCAL)/simple.xml
19+
COMPOSITE=$(XMLLOCAL)/example-composite.xml
2820

2921
# Existing test cases
3022
XMLTESTDIR=$(ROOT)/sbe-tool/src/test/resources
@@ -35,12 +27,27 @@ COMPOSITE4=$(XMLTESTDIR)/composite-elements-schema-rc4.xml
3527
NESTED_GROUP=$(XMLTESTDIR)/group-with-data-schema.xml
3628
FIX_BINARY=$(XMLTESTDIR)/FixBinary.xml
3729

30+
SCHEMA_DIR=$(ROOT)/sbe-samples/src/main/resources
31+
EXAMPLES_SCHEMA=$(SCHEMA_DIR)/example-schema.xml
32+
EXTENSION_SCHEMA=$(SCHEMA_DIR)/example-extension-schema.xml
33+
EXTENSION2_SCHEMA=$(XMLLOCAL)/example-extension-2-schema.xml
34+
GROUP_EXTENSION=$(XMLLOCAL)/group-with-data-extension-schema.xml
35+
3836
# Convenience during development
3937
#SAVE_FORMAT=mkdir -p fmt && cp *.go fmt &&
4038
SAVE_FORMAT=
4139

40+
$(OUTPUTDIR)/example-schema/example-schema: $(SBE_JAR) $(OUTPUTDIR)/baseline/Car.go $(OUTPUTDIR)/extension/Car.go $(OUTPUTDIR)/extension2/Car.go $(OUTPUTDIR)/example-schema/CarExample.go
41+
(export GOPATH=$(GOPATH) && \
42+
cd $(OUTPUTDIR)/example-schema && \
43+
go build && \
44+
go fmt && \
45+
./example-schema)
4246

43-
GeneratedStubExample: $(STUB_EXAMPLE)
47+
clean:
48+
rm -f $(OUTPUTDIR)/baseline/Car.go $(OUTPUTDIR)/extension/Car.go $(OUTPUTDIR)/extension2/Car.go
49+
50+
$(OUTPUTDIR)/baseline/Car.go: $(SBE_JAR)
4451
$(JAVA) \
4552
-Dsbe.output.dir=$(OUTPUTDIR) \
4653
-Dsbe.generate.ir="false" \
@@ -50,13 +57,41 @@ GeneratedStubExample: $(STUB_EXAMPLE)
5057
(export GOPATH=$(GOPATH) && \
5158
cd $(OUTPUTDIR)/baseline && \
5259
go build && \
60+
go fmt && \
5361
go test && \
54-
go install && \
55-
cd $(OUTPUTDIR)/example-schema && \
62+
go install)
63+
64+
$(OUTPUTDIR)/extension/Car.go: $(SBE_JAR)
65+
$(JAVA) \
66+
-Dsbe.output.dir=$(OUTPUTDIR) \
67+
-Dsbe.generate.ir="false" \
68+
-Dsbe.target.language="golang" \
69+
-jar ${SBE_JAR} \
70+
$(EXTENSION_SCHEMA) && \
71+
(export GOPATH=$(GOPATH) && \
72+
cd $(OUTPUTDIR)/extension && \
5673
go build && \
57-
./example-schema)
74+
go install)
5875

59-
test: fix-binary nested-group basic-vardata basic-group basic-types simple composite composite-elements
76+
$(OUTPUTDIR)/extension2/Car.go: $(SBE_JAR)
77+
$(JAVA) \
78+
-Dsbe.output.dir=$(OUTPUTDIR) \
79+
-Dsbe.generate.ir="false" \
80+
-Dsbe.target.language="golang" \
81+
-jar ${SBE_JAR} \
82+
$(EXTENSION2_SCHEMA) && \
83+
(export GOPATH=$(GOPATH) && \
84+
cd $(OUTPUTDIR)/extension2 && \
85+
go build && \
86+
go install)
87+
88+
bench: $(SBE_JAR) $(OUTPUTDIR)/example-schema/example-schema
89+
(export GOPATH=$(GOPATH) && \
90+
cd $(OUTPUTDIR)/example-schema && \
91+
go test --bench . -cpuprofile=cpu.out && \
92+
go tool pprof -text example-schema cpu.out)
93+
94+
test: fix-binary nested-group nested-group-extension basic-vardata basic-group basic-types simple composite composite-elements
6095

6196
fix-binary:
6297
$(JAVA) \
@@ -68,12 +103,14 @@ fix-binary:
68103
-Duser.variant \
69104
-jar ${SBE_JAR} \
70105
$(FIX_BINARY)
71-
(cd $(OUTPUTDIR)/mktdata && \
106+
(export GOPATH=$(GOPATH) && \
107+
cd $(OUTPUTDIR)/mktdata && \
72108
go build && \
73109
$(SAVE_FORMAT) \
74110
go fmt && echo && \
75111
go test)
76112

113+
# Note this one installs so it can be used in the extension below
77114
nested-group:
78115
$(JAVA) \
79116
-Dsbe.output.dir=$(OUTPUTDIR) \
@@ -84,7 +121,26 @@ nested-group:
84121
-Duser.variant \
85122
-jar ${SBE_JAR} \
86123
$(NESTED_GROUP)
87-
(cd $(OUTPUTDIR)/group_with_data && \
124+
(export GOPATH=$(GOPATH) && \
125+
cd $(OUTPUTDIR)/group_with_data && \
126+
go build && \
127+
$(SAVE_FORMAT) \
128+
go fmt && echo && \
129+
go install && \
130+
go test)
131+
132+
nested-group-extension:
133+
$(JAVA) \
134+
-Dsbe.output.dir=$(OUTPUTDIR) \
135+
-Dsbe.target.language=golang \
136+
-Dfile.encoding=US-ASCII \
137+
-Duser.country=US \
138+
-Duser.langimuage=en \
139+
-Duser.variant \
140+
-jar ${SBE_JAR} \
141+
$(GROUP_EXTENSION)
142+
(export GOPATH=$(GOPATH) && \
143+
cd $(OUTPUTDIR)/group_with_data_extension && \
88144
go build && \
89145
$(SAVE_FORMAT) \
90146
go fmt && echo && \
@@ -100,7 +156,8 @@ composite-elements:
100156
-Duser.variant \
101157
-jar ${SBE_JAR} \
102158
$(COMPOSITE4)
103-
(cd $(OUTPUTDIR)/composite_elements && \
159+
(export GOPATH=$(GOPATH) && \
160+
cd $(OUTPUTDIR)/composite_elements && \
104161
go build && \
105162
$(SAVE_FORMAT) \
106163
go fmt && echo && \
@@ -116,7 +173,8 @@ basic-vardata:
116173
-Duser.variant \
117174
-jar ${SBE_JAR} \
118175
$(BASIC_VARDATA)
119-
(cd $(OUTPUTDIR)/vardata/'SBE tests' && \
176+
(export GOPATH=$(GOPATH)/vardata && \
177+
cd $(OUTPUTDIR)/vardata/'SBE tests' && \
120178
go build && \
121179
$(SAVE_FORMAT) \
122180
go fmt && echo && \
@@ -132,7 +190,8 @@ basic-group:
132190
-Duser.variant \
133191
-jar ${SBE_JAR} \
134192
$(BASIC_GROUP)
135-
(cd $(OUTPUTDIR)/group/'SBE tests' && \
193+
(export GOPATH=$(GOPATH)/group && \
194+
cd $(OUTPUTDIR)/group/'SBE tests' && \
136195
go build && \
137196
$(SAVE_FORMAT) \
138197
go fmt && echo && \
@@ -148,7 +207,8 @@ basic-types:
148207
-Duser.variant \
149208
-jar ${SBE_JAR} \
150209
$(BASIC_TYPES)
151-
(cd $(OUTPUTDIR)/basic/'SBE tests' && \
210+
(export GOPATH=$(GOPATH)/basic && \
211+
cd $(OUTPUTDIR)/basic/'SBE tests' && \
152212
go build && \
153213
$(SAVE_FORMAT) \
154214
go fmt && echo && \
@@ -165,8 +225,8 @@ composite:
165225
-Duser.variant \
166226
-jar ${SBE_JAR} \
167227
$(COMPOSITE)
168-
(cd $(OUTPUTDIR)/composite && \
169-
go build && \
228+
(export GOPATH=$(GOPATH) && \
229+
cd $(OUTPUTDIR)/composite && \
170230
$(SAVE_FORMAT) \
171231
go fmt && echo && \
172232
go test)
@@ -181,7 +241,8 @@ simple:
181241
-Duser.variant \
182242
-jar ${SBE_JAR} \
183243
$(SIMPLE)
184-
(cd $(OUTPUTDIR)/simple && \
244+
(export GOPATH=$(GOPATH) && \
245+
cd $(OUTPUTDIR)/simple && \
185246
go build && \
186247
$(SAVE_FORMAT) \
187248
go fmt && echo && \

gocode/README.md

100644100755
Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,58 @@ Getter/Setter method but is instead performed in the Encode and Decode
1414
methods. In general the Encode methods attempt to be strictly
1515
enforcing to ensure only valid SBE is emitted. Where it remains within
1616
the standard the Decode methods attempt to be forgiving in their
17-
interpretation and range checking can be disabled via the the use of
18-
the 'strict' parameter.
17+
interpretation.
18+
19+
To maintain consistency of datastreams, `Encode()` will fail without
20+
writing to the stream, and `Decode()` will fail but will have read (and
21+
where possible decoded) an entire message from the stream.
1922

2023
Secondly, constant values are not set when an object is created. As
2124
golang does not provide constructors, we instead have each support
22-
type Foo provide a FooInit() function which will fill out constant
23-
values. Decoding does fill out constant values.
25+
type `Foo` provide a `FooInit()` function which will fill out constant
26+
values. Decoding automatically fills out constant values.
2427

2528
Some design decisions are based around the structure of sbe-tool
2629
itself. sbe-tool parses the XML into an internal representation (IR)
2730
and then passes this to the language specific generator. As a result
2831
some information on the xml structure has been lost.
2932

30-
An examples of this include the use of the <ref> tag which if used to
33+
An examples of this include the use of the `<ref>` tag which if used to
3134
the same underlying type in a composite will create two differently
3235
named definitions of the type in the IR.
3336

3437
A second example occurs where a field references an aliased primitive
35-
type definition in which case we lose the aliaed type name in the IR
38+
type definition in which case we lose the aliased type name in the IR
3639
as it is unreferenced.
3740

41+
Code Layout
42+
-----------
43+
To match golang's requirement on directory structure and file layout,
44+
the build environment, example and test code are structured into a top
45+
level gocode directory hierarchy.
46+
47+
Code is generated into this structure with pre-existing test code in place.
48+
49+
For the example, the code is generated into a library and the matching
50+
example code lives in it's own directory at the same level. For
51+
example, the example-schema generates the baseline library code into
52+
`gocode/src/baseline` and example code lives in `gocode/src/example-schema`.
53+
54+
To use this layout you should `set GOPATH=/path/to/gocode` or use the
55+
supplied Makefile which does this for you. For the tests you will need
56+
to not have `GOPATH` set or use the supplied Makefile which does this
57+
for you.
58+
59+
Alpha Code Warning
60+
------------------
61+
The golang generator is still under development and the provided APIs
62+
are still subject to change. Some design decisions remain
63+
open. Currently the Car example (and extension) works but this is not
64+
an exhaustive set of features.
65+
66+
67+
Design Notes
68+
============
3869

3970
Primitive Types
4071
---------------
@@ -57,59 +88,47 @@ as a type and a variable with the known constant values is
5788
provided. To preserve name uniqueness within a message the const
5889
values contain the enum type name.
5990

91+
Range Checking of enumeration values is only performed when the
92+
schemaVersion is equal to or greater than the actingVersion so that
93+
new enumeration values are allowed to propogate to older decoders.
94+
6095
Messages and Composites
6196
-----------------------
6297
Messages and composites are both represented as golang structures with
63-
Encode() and Decode() methods amongst others.
98+
`Encode()` and `Decode()` methods amongst others.
6499

65100
Groups and VarData
66101
------------------
67102
Groups and VarData are represented as arrays with their NumInGroup
68-
being implicit in len()
103+
being implicit in `len()`
69104

70105
Semantic Types
71106
--------------
107+
The golang generator provides no special support for semantic
108+
types (as for Java and C++).
72109

73-
The Boolean semantic type is not represented as a golang bool as the
110+
The `Boolean` semantic type is not represented as a golang `bool` as the
74111
spec requires that discrepancies between SinceVersion and
75-
ActingVersion can be resolved using the Null Value.
112+
ActingVersion can be resolved using the NullValue.
76113

77-
The String semantic type is simply represented as a byte array as
114+
The `String` semantic type is simply represented as a byte array as
78115
golang Strings are immutable and are not useful in structures.
79116

80-
[FIXME: insert more here]
81-
82-
83-
Code Layout
84-
-----------
85-
To match golang's requirement on directory structure and file layout,
86-
the build environment, example and test code are structured into a top
87-
level gocode directory hierarchy.
88-
89-
Code is generated into this structure with pre-existing test code in place.
90-
91-
For the example, the code is generated into a library and the matching
92-
example code lives in it's own directory at the same level. For
93-
example the example-schema generates the baseline library code into
94-
gocode/src/baseline and example code lives in gocode/src/example-schema.
95-
96-
To use this layout you will need to set GOPATH=/path/to/gocode or use
97-
the supplied Makefile which does this for you.
117+
The `UTCTimestamp`, `UTCTimeOnly`, `UTCDateOnly` and `MktTime` semantic types
118+
are not represented as a golang `Time` type as none of these semantic
119+
types contain a location. Mapping to a golang `Time` type will be
120+
relatively easy for the application developer who will know the
121+
location and can set it accordingly (null is UTC). They can also
122+
decide what to with golang `Time`'s nanosecond timer when converting
123+
(probably treating it as zero).
98124

99125
Roadmap
100-
-------
101-
* Deprecated support
102-
* Support full Range checking on both Encode and Decode
103-
* Car example-extension-schema works
126+
=======
104127
* Examples documented
105-
* Restructure recursive group generation as it's currently somewhat broken
106-
* Chase up Ennn error message meanings with Real Logic and support?
107-
* go format fixes
108128
* Windows developer support (currently tested on Linux/MacOS)
109129
* Enhance Design/Rationale document (this one)
110130
* presence=optional
111131
* Unnecessary code removal (e.g., GroupSizeEncoding)
112-
* Unicode
132+
* Further Unicode support
113133
* Testing/Bug fixes
114-
* Semantic types (perhaps just date/time, possibly more)
115134
* Benchmarking & Performance Enhancements

0 commit comments

Comments
 (0)