go/bindings: update code to pass structs versions tests
Now we should verify struct data header
if we know the version.
R=jamesr@chromium.org
Review URL: https://codereview.chromium.org/948343008
diff --git a/mojo/go/tests/validation_test.go b/mojo/go/tests/validation_test.go
index d5fc1bc..c7499ff 100644
--- a/mojo/go/tests/validation_test.go
+++ b/mojo/go/tests/validation_test.go
@@ -295,6 +295,10 @@
return v.Proxy.Method10(inParam0)
}
+func (v *conformanceValidator) Method11(inParam0 test.StructG) error {
+ return nil
+}
+
func TestConformanceValidation(t *testing.T) {
tests := getMatchingTests(listTestFiles(), "conformance_")
waiter := bindings.GetAsyncWaiter()
diff --git a/mojo/public/go/bindings/decoder.go b/mojo/public/go/bindings/decoder.go
index 6f6b433..34a230e 100644
--- a/mojo/public/go/bindings/decoder.go
+++ b/mojo/public/go/bindings/decoder.go
@@ -125,22 +125,22 @@
return nil
}
-// StartStruct starts decoding a struct and reads its data header,
-// returning struct version declared in data header.
+// StartStruct starts decoding a struct and reads its data header.
+// Returns the read data header. The caller should check if it is valid.
// Note: it doesn't read a pointer to the encoded struct.
// Call |Finish()| after reading all fields.
-func (d *Decoder) StartStruct() (uint32, error) {
+func (d *Decoder) StartStruct() (DataHeader, error) {
header, err := d.readDataHeader()
if err != nil {
- return 0, err
+ return DataHeader{}, err
}
if header.Size < dataHeaderSize {
- return 0, fmt.Errorf("data header size is too small: is %d, but should be at least %d", header.Size, dataHeaderSize)
+ return DataHeader{}, fmt.Errorf("data header size(%d) should be at least %d", header.Size, dataHeaderSize)
}
if err := d.pushState(header, 0); err != nil {
- return 0, err
+ return DataHeader{}, err
}
- return header.ElementsOrVersion, nil
+ return header, nil
}
func (d *Decoder) readDataHeader() (DataHeader, error) {
diff --git a/mojo/public/go/bindings/message.go b/mojo/public/go/bindings/message.go
index e5c8329..8455cd4 100644
--- a/mojo/public/go/bindings/message.go
+++ b/mojo/public/go/bindings/message.go
@@ -68,10 +68,11 @@
}
func (h *MessageHeader) Decode(decoder *Decoder) error {
- numFields, err := decoder.StartStruct()
+ header, err := decoder.StartStruct()
if err != nil {
return err
}
+ numFields := header.ElementsOrVersion
if numFields < 2 || numFields > 3 {
return fmt.Errorf("Invalid message header: it should have 2 or 3 fileds, but has %d", numFields)
}
diff --git a/mojo/public/tools/bindings/generators/go_templates/source.tmpl b/mojo/public/tools/bindings/generators/go_templates/source.tmpl
index b697cdf..820f113 100644
--- a/mojo/public/tools/bindings/generators/go_templates/source.tmpl
+++ b/mojo/public/tools/bindings/generators/go_templates/source.tmpl
@@ -11,14 +11,11 @@
package {{package}}
import (
- "fmt"
{% for i in imports %}
{{i}}
{% endfor %}
)
-var _ = fmt.Errorf
-
{% import "enum.tmpl" as enum_macros %}
{% import "interface.tmpl" as interface_macros %}
{% import "struct.tmpl" as struct_macros %}
diff --git a/mojo/public/tools/bindings/generators/go_templates/struct.tmpl b/mojo/public/tools/bindings/generators/go_templates/struct.tmpl
index 457e339..27f91ae 100644
--- a/mojo/public/tools/bindings/generators/go_templates/struct.tmpl
+++ b/mojo/public/tools/bindings/generators/go_templates/struct.tmpl
@@ -23,18 +23,32 @@
return nil
}
+var {{struct|name(False)}}_Versions []bindings.DataHeader = []bindings.DataHeader{
+{% for versionInfo in struct.versions %}
+ bindings.DataHeader{{'{'}}{{versionInfo.num_bytes}}, {{versionInfo.version}}{{'}'}},
+{% endfor %}
+}
+
func (s *{{struct|name(exported)}}) Decode(decoder *bindings.Decoder) error {
-{% if struct.bytes %}
- version, err := decoder.StartStruct()
-{% else %}
- _, err := decoder.StartStruct()
-{% endif %}
+ header, err := decoder.StartStruct()
if err != nil {
return err
}
+ index := sort.Search(len({{struct|name(False)}}_Versions), func(i int) bool {
+ return {{struct|name(False)}}_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+ })
+ if index < len({{struct|name(False)}}_Versions) {
+ if {{struct|name(False)}}_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+ index--
+ }
+ expectedSize := {{struct|name(False)}}_Versions[index].Size
+ if expectedSize != header.Size {
+ return fmt.Errorf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size)
+ }
+ }
{% for byte in struct.bytes %}
{% for packed_field in byte.packed_fields %}
- if version >= {{packed_field.min_version}} {
+ if header.ElementsOrVersion >= {{packed_field.min_version}} {
{{decode('s.'~packed_field.field|name(exported), packed_field.field.kind)|tab_indent(2)}}
}
{% endfor %}
diff --git a/mojo/public/tools/bindings/generators/mojom_go_generator.py b/mojo/public/tools/bindings/generators/mojom_go_generator.py
index cb5a16e..536c8ec 100644
--- a/mojo/public/tools/bindings/generators/mojom_go_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_go_generator.py
@@ -259,7 +259,11 @@
all_structs.append(GetResponseStructFromMethod(method))
if len(all_structs) > 0 or len(module.interfaces) > 0:
+ _imports['fmt'] = 'fmt'
_imports['mojo/public/go/bindings'] = 'bindings'
+ if len(all_structs) > 0:
+ _imports['sort'] = 'sort'
+
for struct in all_structs:
for field in struct.fields:
AddImport(module, field.kind)