// Path: cloud-spanner-r2dbc/src/main/java/com/google/cloud/spanner/r2dbc/api/SpannerConnection.java
// public interface SpannerConnection {
//   /**
//    * Allows starting a readonly Cloud Spanner transaction with given staleness settings.
//    *
//    * @param timestampBound staleness settings
//    *
//    * @return {@link Mono} signaling readonly transaction is ready for use
//    */
//   Mono<Void> beginReadonlyTransaction(TimestampBound timestampBound);
// 
//   /**
//    * Allows starting a readonly Cloud Spanner transaction with strong consistency.
//    *
//    * @return {@link Mono} signaling readonly transaction is ready for use
//    */
//   Mono<Void> beginReadonlyTransaction();
// 
//   boolean isInReadonlyTransaction();
// }
// 
// Path: cloud-spanner-r2dbc/src/main/java/com/google/cloud/spanner/r2dbc/statement/StatementParser.java
// public class StatementParser {
// 
//   private static com.google.cloud.spanner.connection.AbstractStatementParser clientLibraryParser =
//       com.google.cloud.spanner.connection.AbstractStatementParser.getInstance(
//           Dialect.GOOGLE_STANDARD_SQL);
// 
//   private StatementParser() {
//     // Prevent instantiation.
//   }
// 
//   /**
//    * Returns the statement type of a given SQL string.
//    *
//    * @param sql the input SQL string.
//    *
//    * @return the type of statement of the SQL string.
//    */
//   public static StatementType getStatementType(String sql) {
//     if (clientLibraryParser.isQuery(sql)) {
//       return StatementType.SELECT;
//     } else if (clientLibraryParser.isDdlStatement(sql)) {
//       return StatementType.DDL;
//     } else if (clientLibraryParser.isUpdateStatement(sql)) {
//       return StatementType.DML;
//     } else {
//       return StatementType.UNKNOWN;
//     }
//   }
// }
// 
// Path: cloud-spanner-r2dbc/src/main/java/com/google/cloud/spanner/r2dbc/statement/StatementType.java
// public enum StatementType {
//   SELECT,
//   DDL,
//   DML,
//   UNKNOWN;
// }


import com.google.cloud.spanner.TimestampBound;
import com.google.cloud.spanner.r2dbc.api.SpannerConnection;
import com.google.cloud.spanner.r2dbc.statement.StatementParser;
import com.google.cloud.spanner.r2dbc.statement.StatementType;
import io.r2dbc.spi.Batch;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionMetadata;
import io.r2dbc.spi.IsolationLevel;
import io.r2dbc.spi.Statement;
import io.r2dbc.spi.TransactionDefinition;
import io.r2dbc.spi.ValidationDepth;
import java.time.Duration;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
  @Override
  public Mono<Void> beginReadonlyTransaction(TimestampBound timestampBound) {
    return this.clientLibraryAdapter.beginReadonlyTransaction(timestampBound);
  }

  @Override
  public Mono<Void> beginReadonlyTransaction() {
    return this.clientLibraryAdapter.beginReadonlyTransaction(TimestampBound.strong());
  }

  @Override
  public Publisher<Void> commitTransaction() {
    return this.clientLibraryAdapter.commitTransaction();
  }

  @Override
  public Batch createBatch() {
    return new SpannerBatch(this.clientLibraryAdapter);
  }

  @Override
  public Publisher<Void> createSavepoint(String name) {
    throw new UnsupportedOperationException();
  }

  @Override
  public Statement createStatement(String query) {
    if (query == null) {
      throw new IllegalArgumentException("Invalid null query.");
    }
// Path: cloud-spanner-r2dbc/src/main/java/com/google/cloud/spanner/r2dbc/api/SpannerConnection.java
// public interface SpannerConnection {
//   /**
//    * Allows starting a readonly Cloud Spanner transaction with given staleness settings.
//    *
//    * @param timestampBound staleness settings
//    *
//    * @return {@link Mono} signaling readonly transaction is ready for use
//    */
//   Mono<Void> beginReadonlyTransaction(TimestampBound timestampBound);
// 
//   /**
//    * Allows starting a readonly Cloud Spanner transaction with strong consistency.
//    *
//    * @return {@link Mono} signaling readonly transaction is ready for use
//    */
//   Mono<Void> beginReadonlyTransaction();
// 
//   boolean isInReadonlyTransaction();
// }
// 
// Path: cloud-spanner-r2dbc/src/main/java/com/google/cloud/spanner/r2dbc/statement/StatementParser.java
// public class StatementParser {
// 
//   private static com.google.cloud.spanner.connection.AbstractStatementParser clientLibraryParser =
//       com.google.cloud.spanner.connection.AbstractStatementParser.getInstance(
//           Dialect.GOOGLE_STANDARD_SQL);
// 
//   private StatementParser() {
//     // Prevent instantiation.
//   }
// 
//   /**
//    * Returns the statement type of a given SQL string.
//    *
//    * @param sql the input SQL string.
//    *
//    * @return the type of statement of the SQL string.
//    */
//   public static StatementType getStatementType(String sql) {
//     if (clientLibraryParser.isQuery(sql)) {
//       return StatementType.SELECT;
//     } else if (clientLibraryParser.isDdlStatement(sql)) {
//       return StatementType.DDL;
//     } else if (clientLibraryParser.isUpdateStatement(sql)) {
//       return StatementType.DML;
//     } else {
//       return StatementType.UNKNOWN;
//     }
//   }
// }
// 
// Path: cloud-spanner-r2dbc/src/main/java/com/google/cloud/spanner/r2dbc/statement/StatementType.java
// public enum StatementType {
//   SELECT,
//   DDL,
//   DML,
//   UNKNOWN;
// }


// Path: cloud-spanner-r2dbc/src/main/java/com/google/cloud/spanner/r2dbc/v2/SpannerClientLibraryConnection.java
import com.google.cloud.spanner.TimestampBound;
import com.google.cloud.spanner.r2dbc.api.SpannerConnection;
import com.google.cloud.spanner.r2dbc.statement.StatementParser;
import com.google.cloud.spanner.r2dbc.statement.StatementType;
import io.r2dbc.spi.Batch;
import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionMetadata;
import io.r2dbc.spi.IsolationLevel;
import io.r2dbc.spi.Statement;
import io.r2dbc.spi.TransactionDefinition;
import io.r2dbc.spi.ValidationDepth;
import java.time.Duration;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;

  @Override
  public Mono<Void> beginReadonlyTransaction(TimestampBound timestampBound) {
    return this.clientLibraryAdapter.beginReadonlyTransaction(timestampBound);
  }

  @Override
  public Mono<Void> beginReadonlyTransaction() {
    return this.clientLibraryAdapter.beginReadonlyTransaction(TimestampBound.strong());
  }

  @Override
  public Publisher<Void> commitTransaction() {
    return this.clientLibraryAdapter.commitTransaction();
  }

  @Override
  public Batch createBatch() {
    return new SpannerBatch(this.clientLibraryAdapter);
  }

  @Override
  public Publisher<Void> createSavepoint(String name) {
    throw new UnsupportedOperationException();
  }

  @Override
  public Statement createStatement(String query) {
    if (query == null) {
      throw new IllegalArgumentException("Invalid null query.");
    }
    StatementType type = StatementParser.getStatementType(query);