[fidl][go] Regression test for File/GetAttr resp

... and a fix: we were not properly re-positioning the head before
encoding/decoding a struct.

Change-Id: I4daf8515b57959f20b17d3e233c12bd0238032af
diff --git a/src/syscall/zx/fidl/bindingstest/impl.go b/src/syscall/zx/fidl/bindingstest/impl.go
index fe7ba71..10acb55 100644
--- a/src/syscall/zx/fidl/bindingstest/impl.go
+++ b/src/syscall/zx/fidl/bindingstest/impl.go
@@ -861,70 +861,6 @@
 	return 48
 }
 
-type Subnet struct {
-	_         struct{} `fidl2:"s,24,4"`
-	Addr      IpAddress
-	PrefixLen uint8
-}
-
-var _mSubnet = _bindings.CreateLazyMarshaler(Subnet{})
-
-func (msg *Subnet) Marshaler() _bindings.Marshaler {
-	return _mSubnet
-}
-
-// Implements Payload.
-func (_ *Subnet) InlineAlignment() int {
-	return 4
-}
-
-// Implements Payload.
-func (_ *Subnet) InlineSize() int {
-	return 24
-}
-
-type IPv4Address struct {
-	_    struct{} `fidl2:"s,4,1"`
-	Addr [4]uint8
-}
-
-var _mIPv4Address = _bindings.CreateLazyMarshaler(IPv4Address{})
-
-func (msg *IPv4Address) Marshaler() _bindings.Marshaler {
-	return _mIPv4Address
-}
-
-// Implements Payload.
-func (_ *IPv4Address) InlineAlignment() int {
-	return 1
-}
-
-// Implements Payload.
-func (_ *IPv4Address) InlineSize() int {
-	return 4
-}
-
-type IPv6Address struct {
-	_    struct{} `fidl2:"s,16,1"`
-	Addr [16]uint8
-}
-
-var _mIPv6Address = _bindings.CreateLazyMarshaler(IPv6Address{})
-
-func (msg *IPv6Address) Marshaler() _bindings.Marshaler {
-	return _mIPv6Address
-}
-
-// Implements Payload.
-func (_ *IPv6Address) InlineAlignment() int {
-	return 1
-}
-
-// Implements Payload.
-func (_ *IPv6Address) InlineSize() int {
-	return 16
-}
-
 type TestAddEthernetDeviceRequest struct {
 	_               struct{} `fidl2:"s,72,8"`
 	TopologicalPath string
@@ -948,6 +884,55 @@
 	return 72
 }
 
+type NodeAttributes struct {
+	_                struct{} `fidl2:"s,56,8"`
+	Mode             uint32
+	Id               uint64
+	ContentSize      uint64
+	StorageSize      uint64
+	LinkCount        uint64
+	CreationTime     uint64
+	ModificationTime uint64
+}
+
+var _mNodeAttributes = _bindings.CreateLazyMarshaler(NodeAttributes{})
+
+func (msg *NodeAttributes) Marshaler() _bindings.Marshaler {
+	return _mNodeAttributes
+}
+
+// Implements Payload.
+func (_ *NodeAttributes) InlineAlignment() int {
+	return 8
+}
+
+// Implements Payload.
+func (_ *NodeAttributes) InlineSize() int {
+	return 56
+}
+
+type TestFileGetAttrResponse struct {
+	_          struct{} `fidl2:"s,64,8"`
+	S          int32
+	Attributes NodeAttributes
+}
+
+var _mTestFileGetAttrResponse = _bindings.CreateLazyMarshaler(TestFileGetAttrResponse{})
+
+func (msg *TestFileGetAttrResponse) Marshaler() _bindings.Marshaler {
+	return _mTestFileGetAttrResponse
+}
+
+// Implements Payload.
+func (_ *TestFileGetAttrResponse) InlineAlignment() int {
+	return 8
+}
+
+// Implements Payload.
+func (_ *TestFileGetAttrResponse) InlineSize() int {
+	return 64
+}
+
 type Union1Tag uint32
 
 const (
@@ -1063,14 +1048,14 @@
 
 const (
 	_ IpAddressConfigTag = iota
-	IpAddressConfigStaticIp
+	IpAddressConfigPaddingSize24Align4
 	IpAddressConfigDhcp
 )
 
 type IpAddressConfig struct {
-	IpAddressConfigTag `fidl:"tag" fidl2:"u,28,4"`
-	StaticIp           Subnet
-	Dhcp               bool
+	IpAddressConfigTag  `fidl:"tag" fidl2:"u,28,4"`
+	PaddingSize24Align4 [6]uint32
+	Dhcp                bool
 }
 
 // Implements Payload.
@@ -1087,9 +1072,9 @@
 	return u.IpAddressConfigTag
 }
 
-func (u *IpAddressConfig) SetStaticIp(staticIp Subnet) {
-	u.IpAddressConfigTag = IpAddressConfigStaticIp
-	u.StaticIp = staticIp
+func (u *IpAddressConfig) SetPaddingSize24Align4(paddingSize24Align4 [6]uint32) {
+	u.IpAddressConfigTag = IpAddressConfigPaddingSize24Align4
+	u.PaddingSize24Align4 = paddingSize24Align4
 }
 
 func (u *IpAddressConfig) SetDhcp(dhcp bool) {
@@ -1097,44 +1082,6 @@
 	u.Dhcp = dhcp
 }
 
-type IpAddressTag uint32
-
-const (
-	_ IpAddressTag = iota
-	IpAddressIpv4
-	IpAddressIpv6
-)
-
-type IpAddress struct {
-	IpAddressTag `fidl:"tag" fidl2:"u,20,4"`
-	Ipv4         IPv4Address
-	Ipv6         IPv6Address
-}
-
-// Implements Payload.
-func (_ *IpAddress) InlineAlignment() int {
-	return 4
-}
-
-// Implements Payload.
-func (_ *IpAddress) InlineSize() int {
-	return 20
-}
-
-func (u *IpAddress) Which() IpAddressTag {
-	return u.IpAddressTag
-}
-
-func (u *IpAddress) SetIpv4(ipv4 IPv4Address) {
-	u.IpAddressTag = IpAddressIpv4
-	u.Ipv4 = ipv4
-}
-
-func (u *IpAddress) SetIpv6(ipv6 IPv6Address) {
-	u.IpAddressTag = IpAddressIpv6
-	u.Ipv6 = ipv6
-}
-
 type SampleXUnionTag uint32
 
 const (
diff --git a/src/syscall/zx/fidl/bindingstest/test.fidl b/src/syscall/zx/fidl/bindingstest/test.fidl
index 6e4aea7..d28fe11 100644
--- a/src/syscall/zx/fidl/bindingstest/test.fidl
+++ b/src/syscall/zx/fidl/bindingstest/test.fidl
@@ -283,3 +283,18 @@
     InterfaceConfig config;
     EthernetDevice device;
 };
+
+struct NodeAttributes {
+    uint32 mode;
+    uint64 id;
+    uint64 content_size;
+    uint64 storage_size;
+    uint64 link_count;
+    uint64 creation_time;
+    uint64 modification_time;
+};
+
+struct TestFileGetAttrResponse {
+    zx.status s;
+    NodeAttributes attributes;
+};
diff --git a/src/syscall/zx/fidl/encoding_new.go b/src/syscall/zx/fidl/encoding_new.go
index a40d219..2233235 100644
--- a/src/syscall/zx/fidl/encoding_new.go
+++ b/src/syscall/zx/fidl/encoding_new.go
@@ -444,6 +444,7 @@
 }
 
 func (m mStruct) marshal(v reflect.Value, out *encoder) error {
+	out.head = align(out.head, m.alignment)
 	for _, field := range m.fields {
 		if err := field.Marshaler.marshal(v.Field(field.index), out); err != nil {
 			return err
@@ -454,6 +455,7 @@
 }
 
 func (m mStruct) unmarshal(in *decoder, v reflect.Value) error {
+	in.head = align(in.head, m.alignment)
 	for _, field := range m.fields {
 		if err := field.Marshaler.unmarshal(in, v.Field(field.index)); err != nil {
 			return err
diff --git a/src/syscall/zx/fidl/fidl_test/encoding_new_test.go b/src/syscall/zx/fidl/fidl_test/encoding_new_test.go
index 1f3c0e1..561de06 100644
--- a/src/syscall/zx/fidl/fidl_test/encoding_new_test.go
+++ b/src/syscall/zx/fidl/fidl_test/encoding_new_test.go
@@ -851,6 +851,32 @@
 			zx.Handle(0xdeadbeef),
 		},
 	}.check(t)
+
+	successCase{
+		name: "file-get-attr-response",
+		input: &TestFileGetAttrResponse{
+			S: 0x7eadbeaf,
+			Attributes: NodeAttributes{
+				Mode:             0x962381a4,
+				Id:               1,
+				ContentSize:      231,
+				StorageSize:      231,
+				LinkCount:        1,
+				CreationTime:     0x8877665544332211,
+				ModificationTime: 0x00ffeeddccbbaa99,
+			},
+		},
+		bytes: []byte{
+			0xaf, 0xbe, 0xad, 0x7e, 0x00, 0x00, 0x00, 0x00,
+			0xa4, 0x81, 0x23, 0x96, 0x00, 0x00, 0x00, 0x00,
+			1, 0, 0, 0, 0, 0, 0, 0,
+			231, 0, 0, 0, 0, 0, 0, 0,
+			231, 0, 0, 0, 0, 0, 0, 0,
+			1, 0, 0, 0, 0, 0, 0, 0,
+			0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+			0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00,
+		},
+	}.check(t)
 }
 
 func TestTableCompatibilityWithXY(t *testing.T) {