// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Generated by
//
//   pkg/front_end/benchmarks/patterns/generate_datatypes.dart

import '../test_datatypes.dart';

abstract class Base4 {
  void dynamicDispatch(Counter counter);

  R accept<R, A>(Visitor4<R, A> visitor, A arg);
}

class Sub0 extends Base4 {
  @override
  void dynamicDispatch(Counter counter) {
    counter.inc();
  }

  void ifThenElseDispatch0(Counter counter) {
    counter.inc();
  }

  void visitorDispatch0(Counter counter) {
    counter.inc();
  }

  @override
  R accept<R, A>(Visitor4<R, A> visitor, A arg) {
    return visitor.visitSub0(this, arg);
  }
}

class Sub1 extends Base4 {
  @override
  void dynamicDispatch(Counter counter) {
    counter.inc();
  }

  void ifThenElseDispatch1(Counter counter) {
    counter.inc();
  }

  void visitorDispatch1(Counter counter) {
    counter.inc();
  }

  @override
  R accept<R, A>(Visitor4<R, A> visitor, A arg) {
    return visitor.visitSub1(this, arg);
  }
}

class Sub2 extends Base4 {
  @override
  void dynamicDispatch(Counter counter) {
    counter.inc();
  }

  void ifThenElseDispatch2(Counter counter) {
    counter.inc();
  }

  void visitorDispatch2(Counter counter) {
    counter.inc();
  }

  @override
  R accept<R, A>(Visitor4<R, A> visitor, A arg) {
    return visitor.visitSub2(this, arg);
  }
}

class Sub3 extends Base4 {
  @override
  void dynamicDispatch(Counter counter) {
    counter.inc();
  }

  void ifThenElseDispatch3(Counter counter) {
    counter.inc();
  }

  void visitorDispatch3(Counter counter) {
    counter.inc();
  }

  @override
  R accept<R, A>(Visitor4<R, A> visitor, A arg) {
    return visitor.visitSub3(this, arg);
  }
}

List<Base4> createData4() {
  return [
    Sub0(),
    Sub1(),
    Sub2(),
    Sub3(),
  ];
}

void incByDynamicDispatch4(Base4 base, Counter counter) {
  base.dynamicDispatch(counter);
}

void incByIfThenElseDispatch4(Base4 base, Counter counter) {
  if (base is Sub0) {
    base.ifThenElseDispatch0(counter);
  } else if (base is Sub1) {
    base.ifThenElseDispatch1(counter);
  } else if (base is Sub2) {
    base.ifThenElseDispatch2(counter);
  } else if (base is Sub3) {
    base.ifThenElseDispatch3(counter);
  }
}

const Visitor4<void, Counter> visitor = CounterVisitor4();

void incByVisitorDispatch4(Base4 base, Counter counter) {
  base.accept(visitor, counter);
}

abstract class Visitor4<R, A> {
  R visitSub0(Sub0 sub, A arg);
  R visitSub1(Sub1 sub, A arg);
  R visitSub2(Sub2 sub, A arg);
  R visitSub3(Sub3 sub, A arg);
}

class CounterVisitor4 implements Visitor4<void, Counter> {
  const CounterVisitor4();

  @override
  void visitSub0(Sub0 sub, Counter counter) {
    sub.visitorDispatch0(counter);
  }

  @override
  void visitSub1(Sub1 sub, Counter counter) {
    sub.visitorDispatch1(counter);
  }

  @override
  void visitSub2(Sub2 sub, Counter counter) {
    sub.visitorDispatch2(counter);
  }

  @override
  void visitSub3(Sub3 sub, Counter counter) {
    sub.visitorDispatch3(counter);
  }
}
