// 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 "src/ast/statement.h"

#include <assert.h>

#include "src/ast/assignment_statement.h"
#include "src/ast/break_statement.h"
#include "src/ast/case_statement.h"
#include "src/ast/continue_statement.h"
#include "src/ast/else_statement.h"
#include "src/ast/fallthrough_statement.h"
#include "src/ast/if_statement.h"
#include "src/ast/kill_statement.h"
#include "src/ast/loop_statement.h"
#include "src/ast/nop_statement.h"
#include "src/ast/regardless_statement.h"
#include "src/ast/return_statement.h"
#include "src/ast/switch_statement.h"
#include "src/ast/unless_statement.h"
#include "src/ast/variable_statement.h"

namespace tint {
namespace ast {

Statement::Statement() = default;

Statement::Statement(const Source& source) : Node(source) {}

Statement::~Statement() = default;

AssignmentStatement* Statement::AsAssign() {
  assert(IsAssign());
  return static_cast<AssignmentStatement*>(this);
}

BreakStatement* Statement::AsBreak() {
  assert(IsBreak());
  return static_cast<BreakStatement*>(this);
}

CaseStatement* Statement::AsCase() {
  assert(IsCase());
  return static_cast<CaseStatement*>(this);
}

ContinueStatement* Statement::AsContinue() {
  assert(IsContinue());
  return static_cast<ContinueStatement*>(this);
}

ElseStatement* Statement::AsElse() {
  assert(IsElse());
  return static_cast<ElseStatement*>(this);
}

FallthroughStatement* Statement::AsFallthrough() {
  assert(IsFallthrough());
  return static_cast<FallthroughStatement*>(this);
}

IfStatement* Statement::AsIf() {
  assert(IsIf());
  return static_cast<IfStatement*>(this);
}

KillStatement* Statement::AsKill() {
  assert(IsKill());
  return static_cast<KillStatement*>(this);
}

LoopStatement* Statement::AsLoop() {
  assert(IsLoop());
  return static_cast<LoopStatement*>(this);
}

NopStatement* Statement::AsNop() {
  assert(IsNop());
  return static_cast<NopStatement*>(this);
}

RegardlessStatement* Statement::AsRegardless() {
  assert(IsRegardless());
  return static_cast<RegardlessStatement*>(this);
}

ReturnStatement* Statement::AsReturn() {
  assert(IsReturn());
  return static_cast<ReturnStatement*>(this);
}

SwitchStatement* Statement::AsSwitch() {
  assert(IsSwitch());
  return static_cast<SwitchStatement*>(this);
}

UnlessStatement* Statement::AsUnless() {
  assert(IsUnless());
  return static_cast<UnlessStatement*>(this);
}

VariableStatement* Statement::AsVariable() {
  assert(IsVariable());
  return static_cast<VariableStatement*>(this);
}

}  // namespace ast
}  // namespace tint
