// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>

#include "src/ast/array_accessor_expression.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/binary_expression.h"
#include "src/ast/decorated_variable.h"
#include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/member_accessor_expression.h"
#include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/sint_literal.h"
#include "src/ast/stride_decoration.h"
#include "src/ast/struct.h"
#include "src/ast/struct_member.h"
#include "src/ast/struct_member_offset_decoration.h"
#include "src/ast/type/array_type.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/struct_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/context.h"
#include "src/type_determiner.h"
#include "src/writer/hlsl/test_helper.h"

namespace tint {
namespace writer {
namespace hlsl {
namespace {

using HlslGeneratorImplTest_MemberAccessor = TestHelper;

TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
  ast::type::F32Type f32;

  ast::StructMemberList members;
  ast::StructMemberDecorationList deco;
  deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("mem", &f32, deco));

  auto* strct = create<ast::Struct>();
  strct->set_members(members);

  ast::type::StructType s("Str", strct);

  auto* str_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("str", ast::StorageClass::kPrivate, &s));

  auto* str = create<ast::IdentifierExpression>("str");
  auto* mem = create<ast::IdentifierExpression>("mem");

  ast::MemberAccessorExpression expr(str, mem);

  td.RegisterVariableForTesting(str_var);
  gen.register_global(str_var);
  mod.AddGlobalVariable(str_var);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "str.mem");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load) {
  // struct Data {
  //   [[offset(0)]] a : i32;
  //   [[offset(4)]] b : f32;
  // };
  // var<storage_buffer> data : Data;
  // data.b;
  //
  // -> asfloat(data.Load(4));
  ast::type::F32Type f32;
  ast::type::I32Type i32;

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
  members.push_back(create<ast::StructMember>("b", &f32, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                     create<ast::IdentifierExpression>("b"));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr));

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asfloat(data.Load(4))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_Int) {
  // struct Data {
  //   [[offset(0)]] a : i32;
  //   [[offset(4)]] b : f32;
  // };
  // var<storage_buffer> data : Data;
  // data.a;
  //
  // -> asint(data.Load(0));
  ast::type::F32Type f32;
  ast::type::I32Type i32;

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
  members.push_back(create<ast::StructMember>("b", &f32, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                     create<ast::IdentifierExpression>("a"));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr));

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asint(data.Load(0))");
}
TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix) {
  // struct Data {
  //   [[offset(0)]] z : f32;
  //   [[offset(4)]] a : mat2x3<f32>;
  // };
  // var<storage_buffer> data : Data;
  // mat2x3<f32> b;
  // data.a = b;
  //
  // -> float3x2 _tint_tmp = b;
  //    data.Store3(4 + 0, asuint(_tint_tmp[0]));
  //    data.Store3(4 + 16, asuint(_tint_tmp[1]));
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::MatrixType mat(&f32, 3, 2);

  auto* str = create<ast::Struct>();
  str->set_members({
      create<ast::StructMember>(
          "z", &i32,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
      create<ast::StructMember>(
          "a", &mat,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(4, Source{})}),
  });

  ast::type::StructType s("Data", str);

  auto* b_var = create<ast::Variable>("b", ast::StorageClass::kPrivate, &mat);

  auto* coord_var =
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s);

  auto* lhs = create<ast::MemberAccessorExpression>(
      create<ast::IdentifierExpression>("data"),
      create<ast::IdentifierExpression>("a"));
  auto* rhs = create<ast::IdentifierExpression>("b");

  ast::AssignmentStatement assign(lhs, rhs);

  td.RegisterVariableForTesting(coord_var);
  td.RegisterVariableForTesting(b_var);
  gen.register_global(coord_var);
  gen.register_global(b_var);
  mod.AddGlobalVariable(coord_var);
  mod.AddGlobalVariable(b_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&assign));

  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(result(), R"(float3x2 _tint_tmp = b;
data.Store3(4 + 0, asuint(_tint_tmp[0]));
data.Store3(4 + 16, asuint(_tint_tmp[1]));
)");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix_Empty) {
  // struct Data {
  //   [[offset(0)]] z : f32;
  //   [[offset(4)]] a : mat2x3<f32>;
  // };
  // var<storage_buffer> data : Data;
  // data.a = mat2x3<f32>();
  //
  // -> float3x2 _tint_tmp = float3x2(0.0f, 0.0f, 0.0f,
  // 0.0f, 0.0f, 0.0f);
  //    data.Store3(4 + 0, asuint(_tint_tmp[0]);
  //    data.Store3(4 + 16, asuint(_tint_tmp[1]));
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::MatrixType mat(&f32, 3, 2);

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("z", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
  members.push_back(create<ast::StructMember>("a", &mat, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  auto* lhs = create<ast::MemberAccessorExpression>(
      create<ast::IdentifierExpression>("data"),
      create<ast::IdentifierExpression>("a"));
  auto* rhs =
      create<ast::TypeConstructorExpression>(&mat, ast::ExpressionList{});

  ast::AssignmentStatement assign(lhs, rhs);

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&assign));

  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(
      result(),
      R"(float3x2 _tint_tmp = float3x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
data.Store3(4 + 0, asuint(_tint_tmp[0]));
data.Store3(4 + 16, asuint(_tint_tmp[1]));
)");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix) {
  // struct Data {
  //   [[offset(0)]] z : f32;
  //   [[offset(4)]] a : mat3x2<f32>;
  // };
  // var<storage_buffer> data : Data;
  // data.a;
  //
  // -> asfloat(uint2x3(data.Load2(4 + 0), data.Load2(4 + 8),
  // data.Load2(4 + 16)));
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::MatrixType mat(&f32, 2, 3);

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("z", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
  members.push_back(create<ast::StructMember>("a", &mat, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                     create<ast::IdentifierExpression>("a"));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr));

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(),
            "asfloat(uint2x3(data.Load2(4 + 0), data.Load2(4 + 8), "
            "data.Load2(4 + 16)))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_Nested) {
  // struct Data {
  //   [[offset(0)]] z : f32;
  //   [[offset(4)]] a : mat2x3<f32;
  // };
  // struct Outer {
  //   [[offset(0)]] c : f32;
  //   [[offset(4)]] b : Data;
  // };
  // var<storage_buffer> data : Outer;
  // data.b.a;
  //
  // -> asfloat(uint3x2(data.Load3(4 + 0), data.Load3(4 + 16)));
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::MatrixType mat(&f32, 3, 2);

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("z", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
  members.push_back(create<ast::StructMember>("a", &mat, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                     create<ast::IdentifierExpression>("a"));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr));

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(),
            "asfloat(uint3x2(data.Load3(4 + 0), data.Load3(4 + 16)))");
}

TEST_F(
    HlslGeneratorImplTest_MemberAccessor,
    EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_By3_Is_16_Bytes) {
  // struct Data {
  //   [[offset(4)]] a : mat3x3<f32;
  // };
  // var<storage_buffer> data : Data;
  // data.a;
  //
  // -> asfloat(uint3x3(data.Load3(0), data.Load3(16),
  // data.Load3(32)));
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::MatrixType mat(&f32, 3, 3);

  ast::StructMemberList members;
  ast::StructMemberDecorationList deco;
  deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &mat, deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                     create<ast::IdentifierExpression>("a"));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr));

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(),
            "asfloat(uint3x3(data.Load3(0 + 0), data.Load3(0 + 16), "
            "data.Load3(0 + 32)))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_Single_Element) {
  // struct Data {
  //   [[offset(0)]] z : f32;
  //   [[offset(16)]] a : mat4x3<f32>;
  // };
  // var<storage_buffer> data : Data;
  // data.a[2][1];
  //
  // -> asfloat(data.Load((2 * 16) + (1 * 4) + 16)))
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::MatrixType mat(&f32, 3, 4);

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("z", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
  members.push_back(create<ast::StructMember>("a", &mat, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::ArrayAccessorExpression expr(
      create<ast::ArrayAccessorExpression>(
          create<ast::MemberAccessorExpression>(
              create<ast::IdentifierExpression>("data"),
              create<ast::IdentifierExpression>("a")),
          create<ast::ScalarConstructorExpression>(
              create<ast::SintLiteral>(&i32, 2))),
      create<ast::ScalarConstructorExpression>(
          create<ast::SintLiteral>(&i32, 1)));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr));

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + (16 * 2) + 16))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray) {
  // struct Data {
  //   [[offset(0)]] a : [[stride(4)]] array<i32, 5>;
  // };
  // var<storage_buffer> data : Data;
  // data.a[2];
  //
  // -> asint(data.Load((2 * 4));
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::ArrayType ary(&i32, 5);
  ary.set_decorations({create<ast::StrideDecoration>(4, Source{})});

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &ary, a_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::ArrayAccessorExpression expr(
      create<ast::MemberAccessorExpression>(
          create<ast::IdentifierExpression>("data"),
          create<ast::IdentifierExpression>("a")),
      create<ast::ScalarConstructorExpression>(
          create<ast::SintLiteral>(&i32, 2)));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asint(data.Load((4 * 2) + 0))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
  // struct Data {
  //   [[offset(0)]] a : [[stride(4)]] array<i32, 5>;
  // };
  // var<storage_buffer> data : Data;
  // data.a[(2 + 4) - 3];
  //
  // -> asint(data.Load((4 * ((2 + 4) - 3)));
  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::ArrayType ary(&i32, 5);
  ary.set_decorations({create<ast::StrideDecoration>(4, Source{})});

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &ary, a_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  ast::ArrayAccessorExpression expr(
      create<ast::MemberAccessorExpression>(
          create<ast::IdentifierExpression>("data"),
          create<ast::IdentifierExpression>("a")),
      create<ast::BinaryExpression>(
          ast::BinaryOp::kSubtract,
          create<ast::BinaryExpression>(
              ast::BinaryOp::kAdd,
              create<ast::ScalarConstructorExpression>(
                  create<ast::SintLiteral>(&i32, 2)),
              create<ast::ScalarConstructorExpression>(
                  create<ast::SintLiteral>(&i32, 4))),
          create<ast::ScalarConstructorExpression>(
              create<ast::SintLiteral>(&i32, 3))));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();

  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asint(data.Load((4 * ((2 + 4) - 3)) + 0))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store) {
  // struct Data {
  //   [[offset(0)]] a : i32;
  //   [[offset(4)]] b : f32;
  // };
  // var<storage_buffer> data : Data;
  // data.b = 2.3f;
  //
  // -> data.Store(0, asuint(2.0f));

  ast::type::F32Type f32;
  ast::type::I32Type i32;

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
  members.push_back(create<ast::StructMember>("b", &f32, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  auto* lhs = create<ast::MemberAccessorExpression>(
      create<ast::IdentifierExpression>("data"),
      create<ast::IdentifierExpression>("b"));
  auto* rhs = create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&f32, 2.0f));
  ast::AssignmentStatement assign(lhs, rhs);

  ASSERT_TRUE(td.DetermineResultType(&assign));
  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(result(), R"(data.Store(4, asuint(2.0f));
)");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store_ToArray) {
  // struct Data {
  //   [[offset(0)]] a : [[stride(4)]] array<i32, 5>;
  // };
  // var<storage_buffer> data : Data;
  // data.a[2] = 2;
  //
  // -> data.Store((2 * 4), asuint(2.3f));

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::ArrayType ary(&i32, 5);
  ary.set_decorations({create<ast::StrideDecoration>(4, Source{})});

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &ary, a_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  auto* lhs = create<ast::ArrayAccessorExpression>(
      create<ast::MemberAccessorExpression>(
          create<ast::IdentifierExpression>("data"),
          create<ast::IdentifierExpression>("a")),
      create<ast::ScalarConstructorExpression>(
          create<ast::SintLiteral>(&i32, 2)));
  auto* rhs = create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 2));
  ast::AssignmentStatement assign(lhs, rhs);

  ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(result(), R"(data.Store((4 * 2) + 0, asuint(2));
)");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store_Int) {
  // struct Data {
  //   [[offset(0)]] a : i32;
  //   [[offset(4)]] b : f32;
  // };
  // var<storage_buffer> data : Data;
  // data.a = 2;
  //
  // -> data.Store(0, asuint(2));

  ast::type::F32Type f32;
  ast::type::I32Type i32;

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &i32, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(4, Source{}));
  members.push_back(create<ast::StructMember>("b", &f32, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  auto* lhs = create<ast::MemberAccessorExpression>(
      create<ast::IdentifierExpression>("data"),
      create<ast::IdentifierExpression>("a"));
  auto* rhs = create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 2));
  ast::AssignmentStatement assign(lhs, rhs);

  ASSERT_TRUE(td.DetermineResultType(&assign));
  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(result(), R"(data.Store(0, asuint(2));
)");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_Vec3) {
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // var<storage_buffer> data : Data;
  // data.b;
  //
  // -> asfloat(data.Load(16));

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &ivec3, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
  members.push_back(create<ast::StructMember>("b", &fvec3, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  ast::MemberAccessorExpression expr(create<ast::IdentifierExpression>("data"),
                                     create<ast::IdentifierExpression>("b"));

  ASSERT_TRUE(td.DetermineResultType(&expr));
  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asfloat(data.Load3(16))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store_Vec3) {
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // var<storage_buffer> data : Data;
  // data.b = vec3<f32>(2.3f, 1.2f, 0.2f);
  //
  // -> data.Store(16, asuint(float3(2.3f, 1.2f, 0.2f)));

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  ast::StructMemberList members;
  ast::StructMemberDecorationList a_deco;
  a_deco.push_back(create<ast::StructMemberOffsetDecoration>(0, Source{}));
  members.push_back(create<ast::StructMember>("a", &ivec3, a_deco));

  ast::StructMemberDecorationList b_deco;
  b_deco.push_back(create<ast::StructMemberOffsetDecoration>(16, Source{}));
  members.push_back(create<ast::StructMember>("b", &fvec3, b_deco));

  auto* str = create<ast::Struct>();
  str->set_members(members);

  ast::type::StructType s("Data", str);

  auto* coord_var = create<ast::DecoratedVariable>(
      create<ast::Variable>("data", ast::StorageClass::kStorageBuffer, &s));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  auto* lit1 = create<ast::FloatLiteral>(&f32, 1.f);
  auto* lit2 = create<ast::FloatLiteral>(&f32, 2.f);
  auto* lit3 = create<ast::FloatLiteral>(&f32, 3.f);
  ast::ExpressionList values;
  values.push_back(create<ast::ScalarConstructorExpression>(lit1));
  values.push_back(create<ast::ScalarConstructorExpression>(lit2));
  values.push_back(create<ast::ScalarConstructorExpression>(lit3));

  auto* lhs = create<ast::MemberAccessorExpression>(
      create<ast::IdentifierExpression>("data"),
      create<ast::IdentifierExpression>("b"));
  auto* rhs = create<ast::TypeConstructorExpression>(&fvec3, values);

  ast::AssignmentStatement assign(lhs, rhs);

  ASSERT_TRUE(td.DetermineResultType(&assign));
  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(result(),
            R"(data.Store3(16, asuint(float3(1.0f, 2.0f, 3.0f)));
)");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel) {
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // struct Pre {
  //   var c : [[stride(32)]] array<Data, 4>;
  // };
  //
  // var<storage_buffer> data : Pre;
  // data.c[2].b
  //
  // -> asfloat(data.Load3(16 + (2 * 32)))

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  auto* data_str = create<ast::Struct>();
  data_str->set_members({
      create<ast::StructMember>(
          "a", &ivec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
      create<ast::StructMember>(
          "b", &fvec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(16, Source{})}),
  });

  ast::type::StructType data("Data", data_str);

  ast::type::ArrayType ary(&data, 4);
  ary.set_decorations({create<ast::StrideDecoration>(32, Source{})});

  auto* pre_str = create<ast::Struct>();
  pre_str->set_members({
      create<ast::StructMember>(
          "c", &ary,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
  });

  ast::type::StructType pre_struct("Pre", pre_str);

  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
      "data", ast::StorageClass::kStorageBuffer, &pre_struct));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  ast::MemberAccessorExpression expr(
      create<ast::ArrayAccessorExpression>(
          create<ast::MemberAccessorExpression>(
              create<ast::IdentifierExpression>("data"),
              create<ast::IdentifierExpression>("c")),
          create<ast::ScalarConstructorExpression>(
              create<ast::SintLiteral>(&i32, 2))),
      create<ast::IdentifierExpression>("b"));

  ASSERT_TRUE(td.DetermineResultType(&expr));
  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Swizzle) {
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // struct Pre {
  //   var c : [[stride(32)]] array<Data, 4>;
  // };
  //
  // var<storage_buffer> data : Pre;
  // data.c[2].b.xy
  //
  // -> asfloat(data.Load3(16 + (2 * 32))).xy

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  ast::StructMemberList members;
  ast::StructMemberDecorationList deco;

  auto* data_str = create<ast::Struct>();
  data_str->set_members({
      create<ast::StructMember>(
          "a", &ivec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
      create<ast::StructMember>(
          "b", &fvec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(16, Source{})}),
  });

  ast::type::StructType data("Data", data_str);

  ast::type::ArrayType ary(&data, 4);
  ary.set_decorations({create<ast::StrideDecoration>(32, Source{})});

  auto* pre_str = create<ast::Struct>();
  pre_str->set_members({create<ast::StructMember>(
      "c", &ary,
      ast::StructMemberDecorationList{
          create<ast::StructMemberOffsetDecoration>(0, Source{})})});

  ast::type::StructType pre_struct("Pre", pre_str);

  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
      "data", ast::StorageClass::kStorageBuffer, &pre_struct));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  ast::MemberAccessorExpression expr(
      create<ast::MemberAccessorExpression>(
          create<ast::ArrayAccessorExpression>(
              create<ast::MemberAccessorExpression>(
                  create<ast::IdentifierExpression>("data"),
                  create<ast::IdentifierExpression>("c")),
              create<ast::ScalarConstructorExpression>(
                  create<ast::SintLiteral>(&i32, 2))),
          create<ast::IdentifierExpression>("b")),
      create<ast::IdentifierExpression>("xy"));

  ASSERT_TRUE(td.DetermineResultType(&expr));
  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0)).xy");
}

TEST_F(
    HlslGeneratorImplTest_MemberAccessor,
    EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Swizzle_SingleLetter) {  // NOLINT
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // struct Pre {
  //   var c : [[stride(32)]] array<Data, 4>;
  // };
  //
  // var<storage_buffer> data : Pre;
  // data.c[2].b.g
  //
  // -> asfloat(data.Load((4 * 1) + 16 + (2 * 32) + 0))

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  auto* data_str = create<ast::Struct>();
  data_str->set_members({
      create<ast::StructMember>(
          "a", &ivec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
      create<ast::StructMember>(
          "b", &fvec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(16, Source{})}),
  });

  ast::type::StructType data("Data", data_str);

  ast::type::ArrayType ary(&data, 4);
  ary.set_decorations({create<ast::StrideDecoration>(32, Source{})});

  auto* pre_str = create<ast::Struct>();
  pre_str->set_members({create<ast::StructMember>(
      "c", &ary,
      ast::StructMemberDecorationList{
          create<ast::StructMemberOffsetDecoration>(0, Source{})})});

  ast::type::StructType pre_struct("Pre", pre_str);

  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
      "data", ast::StorageClass::kStorageBuffer, &pre_struct));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  ast::MemberAccessorExpression expr(
      create<ast::MemberAccessorExpression>(
          create<ast::ArrayAccessorExpression>(
              create<ast::MemberAccessorExpression>(
                  create<ast::IdentifierExpression>("data"),
                  create<ast::IdentifierExpression>("c")),
              create<ast::ScalarConstructorExpression>(
                  create<ast::SintLiteral>(&i32, 2))),
          create<ast::IdentifierExpression>("b")),
      create<ast::IdentifierExpression>("g"));

  ASSERT_TRUE(td.DetermineResultType(&expr));
  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Index) {
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // struct Pre {
  //   var c : [[stride(32)]] array<Data, 4>;
  // };
  //
  // var<storage_buffer> data : Pre;
  // data.c[2].b[1]
  //
  // -> asfloat(data.Load(4 + 16 + (2 * 32)))

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  auto* data_str = create<ast::Struct>();
  data_str->set_members({
      create<ast::StructMember>(
          "a", &ivec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
      create<ast::StructMember>(
          "b", &fvec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(16, Source{})}),
  });

  ast::type::StructType data("Data", data_str);

  ast::type::ArrayType ary(&data, 4);
  ary.set_decorations({create<ast::StrideDecoration>(32, Source{})});

  auto* pre_str = create<ast::Struct>();
  pre_str->set_members({create<ast::StructMember>(
      "c", &ary,
      ast::StructMemberDecorationList{
          create<ast::StructMemberOffsetDecoration>(0, Source{})})});

  ast::type::StructType pre_struct("Pre", pre_str);

  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
      "data", ast::StorageClass::kStorageBuffer, &pre_struct));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  ast::ArrayAccessorExpression expr(
      create<ast::MemberAccessorExpression>(
          create<ast::ArrayAccessorExpression>(
              create<ast::MemberAccessorExpression>(
                  create<ast::IdentifierExpression>("data"),
                  create<ast::IdentifierExpression>("c")),
              create<ast::ScalarConstructorExpression>(
                  create<ast::SintLiteral>(&i32, 2))),
          create<ast::IdentifierExpression>("b")),
      create<ast::ScalarConstructorExpression>(
          create<ast::SintLiteral>(&i32, 1)));

  ASSERT_TRUE(td.DetermineResultType(&expr));
  ASSERT_TRUE(gen.EmitExpression(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store_MultiLevel) {
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // struct Pre {
  //   var c : [[stride(32)]] array<Data, 4>;
  // };
  //
  // var<storage_buffer> data : Pre;
  // data.c[2].b = vec3<f32>(1.f, 2.f, 3.f);
  //
  // -> data.Store3(16 + (2 * 32), asuint(float3(1.0f, 2.0f, 3.0f)));

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  auto* data_str = create<ast::Struct>();
  data_str->set_members({
      create<ast::StructMember>(
          "a", &ivec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
      create<ast::StructMember>(
          "b", &fvec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(16, Source{})}),
  });

  ast::type::StructType data("Data", data_str);

  ast::type::ArrayType ary(&data, 4);
  ary.set_decorations({create<ast::StrideDecoration>(32, Source{})});

  auto* pre_str = create<ast::Struct>();
  pre_str->set_members({create<ast::StructMember>(
      "c", &ary,
      ast::StructMemberDecorationList{
          create<ast::StructMemberOffsetDecoration>(0, Source{})})});

  ast::type::StructType pre_struct("Pre", pre_str);

  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
      "data", ast::StorageClass::kStorageBuffer, &pre_struct));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  auto* lhs = create<ast::MemberAccessorExpression>(
      create<ast::ArrayAccessorExpression>(
          create<ast::MemberAccessorExpression>(
              create<ast::IdentifierExpression>("data"),
              create<ast::IdentifierExpression>("c")),
          create<ast::ScalarConstructorExpression>(
              create<ast::SintLiteral>(&i32, 2))),
      create<ast::IdentifierExpression>("b"));

  auto* lit1 = create<ast::FloatLiteral>(&f32, 1.f);
  auto* lit2 = create<ast::FloatLiteral>(&f32, 2.f);
  auto* lit3 = create<ast::FloatLiteral>(&f32, 3.f);
  ast::ExpressionList values;
  values.push_back(create<ast::ScalarConstructorExpression>(lit1));
  values.push_back(create<ast::ScalarConstructorExpression>(lit2));
  values.push_back(create<ast::ScalarConstructorExpression>(lit3));

  auto* rhs = create<ast::TypeConstructorExpression>(&fvec3, values);

  ast::AssignmentStatement assign(lhs, rhs);

  ASSERT_TRUE(td.DetermineResultType(&assign));
  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(result(),
            R"(data.Store3(16 + (32 * 2) + 0, asuint(float3(1.0f, 2.0f, 3.0f)));
)");
}

TEST_F(HlslGeneratorImplTest_MemberAccessor,
       EmitExpression_MemberAccessor_StorageBuffer_Store_Swizzle_SingleLetter) {
  // struct Data {
  //   [[offset(0)]] a : vec3<i32>;
  //   [[offset(16)]] b : vec3<f32>;
  // };
  // struct Pre {
  //   var c : [[stride(32)]] array<Data, 4>;
  // };
  //
  // var<storage_buffer> data : Pre;
  // data.c[2].b.y = 1.f;
  //
  // -> data.Store((4 * 1) + 16 + (2 * 32) + 0, asuint(1.0f));

  ast::type::F32Type f32;
  ast::type::I32Type i32;
  ast::type::VectorType ivec3(&i32, 3);
  ast::type::VectorType fvec3(&f32, 3);

  auto* data_str = create<ast::Struct>();
  data_str->set_members({
      create<ast::StructMember>(
          "a", &ivec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(0, Source{})}),
      create<ast::StructMember>(
          "b", &fvec3,
          ast::StructMemberDecorationList{
              create<ast::StructMemberOffsetDecoration>(16, Source{})}),
  });

  ast::type::StructType data("Data", data_str);

  ast::type::ArrayType ary(&data, 4);
  ary.set_decorations({create<ast::StrideDecoration>(32, Source{})});

  auto* pre_str = create<ast::Struct>();
  pre_str->set_members({create<ast::StructMember>(
      "c", &ary,
      ast::StructMemberDecorationList{
          create<ast::StructMemberOffsetDecoration>(0, Source{})})});

  ast::type::StructType pre_struct("Pre", pre_str);

  auto* coord_var = create<ast::DecoratedVariable>(create<ast::Variable>(
      "data", ast::StorageClass::kStorageBuffer, &pre_struct));

  td.RegisterVariableForTesting(coord_var);
  gen.register_global(coord_var);
  mod.AddGlobalVariable(coord_var);

  ASSERT_TRUE(td.Determine()) << td.error();

  auto* lhs = create<ast::MemberAccessorExpression>(
      create<ast::MemberAccessorExpression>(
          create<ast::ArrayAccessorExpression>(
              create<ast::MemberAccessorExpression>(
                  create<ast::IdentifierExpression>("data"),
                  create<ast::IdentifierExpression>("c")),
              create<ast::ScalarConstructorExpression>(
                  create<ast::SintLiteral>(&i32, 2))),
          create<ast::IdentifierExpression>("b")),
      create<ast::IdentifierExpression>("y"));

  auto* rhs = create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&i32, 1.f));

  ast::AssignmentStatement assign(lhs, rhs);

  ASSERT_TRUE(td.DetermineResultType(&assign));
  ASSERT_TRUE(gen.EmitStatement(out, &assign)) << gen.error();
  EXPECT_EQ(result(),
            R"(data.Store((4 * 1) + 16 + (32 * 2) + 0, asuint(1.0f));
)");
}

}  // namespace
}  // namespace hlsl
}  // namespace writer
}  // namespace tint
