diff --git a/.github/workflows/conformance-tests-bigtable-emulator.yaml b/.github/workflows/conformance-tests-bigtable-emulator.yaml
new file mode 100644
index 000000000000..f5be56cb92b3
--- /dev/null
+++ b/.github/workflows/conformance-tests-bigtable-emulator.yaml
@@ -0,0 +1,58 @@
+# Copyright 2025 Google LLC
+#
+# 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.
+# Github action job to test core java library features on
+# downstream client libraries before they are released.
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - 'Bigtable/**'
+ - '.github/workflows/conformance-tests-bigtable-emulator.yaml'
+ pull_request:
+ paths:
+ - 'Bigtable/**'
+ - '.github/workflows/conformance-tests-bigtable-emulator.yaml'
+ workflow_dispatch:
+name: Run Bigtable Conformance Tests With Emulator
+jobs:
+ conformance:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.1'
+ extensions: grpc
+
+ - name: Checkout Bigtable conformance tests
+ uses: actions/checkout@v4
+ with:
+ repository: googleapis/cloud-bigtable-clients-test
+ ref: main
+ path: cloud-bigtable-clients-test
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: '>=1.20.2'
+
+ - name: Install Road Runner PHP
+ run: |
+ wget https://github.com/roadrunner-server/roadrunner/releases/download/v2024.3.1/roadrunner-2024.3.1-linux-amd64.deb
+ sudo dpkg -i roadrunner-2024.3.1-linux-amd64.deb
+
+ - run: bash .kokoro/conformance.sh
diff --git a/.github/workflows/conformance-tests-storage-emulator.yaml b/.github/workflows/conformance-tests-storage-emulator.yaml
index 1aceb06d3923..58a82d93ac65 100644
--- a/.github/workflows/conformance-tests-storage-emulator.yaml
+++ b/.github/workflows/conformance-tests-storage-emulator.yaml
@@ -4,11 +4,11 @@ on:
- main
paths:
- 'Storage/**'
- - '.github/workflows/emulator-conformance-tests-storage.yaml'
+ - '.github/workflows/conformance-tests-storage-emulator.yaml'
pull_request:
paths:
- 'Storage/**'
- - '.github/workflows/emulator-conformance-tests-storage.yaml'
+ - '.github/workflows/conformance-tests-storage-emulator.yaml'
name: Run Storage Retry Conformance Tests With Emulator
jobs:
test:
diff --git a/.kokoro/conformance.sh b/.kokoro/conformance.sh
new file mode 100644
index 000000000000..570a7989fd52
--- /dev/null
+++ b/.kokoro/conformance.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# Copyright 2025 Google LLC
+#
+# 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.
+
+set -eo pipefail
+
+## Get the directory of the build script
+scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}"))
+## cd to the parent directory, i.e. the root of the git repo
+cd ${scriptDir}/..
+
+composer update -d Bigtable/tests/Conformance/proxy
+
+set +e
+
+# declare -a configs=("default" "enable_all")
+declare -a configs=("default") # PHP only supports "default" feature flags for now
+for config in "${configs[@]}"
+do
+ # Start the proxy in a separate process
+ rr serve -w Bigtable/tests/Conformance/proxy &
+ proxyPID=$!
+
+ # Run the conformance test
+ if [[ ${config} = "enable_all" ]]
+ then
+ echo "Testing the client with all optional features enabled..."
+ configFlag="--enable_features_all"
+ else
+ echo "Testing the client with default settings for optional features..."
+ # skipping routing cookie and retry info tests. When the feature is disabled, these
+ # tests are expected to fail
+ configFlag="-skip _Retry_WithRoutingCookie\|_Retry_WithRetryInfo"
+ fi
+
+ pushd .
+ cd cloud-bigtable-clients-test/tests
+ # If there is known failures, please add
+ # "-skip `cat ../../test-proxy/known_failures.txt`" to the command below.
+ eval "go test -v -proxy_addr=:9999 ${configFlag}"
+ returnCode=$?
+ popd
+
+ # Stop the proxy
+ kill ${proxyPID}
+
+ if [[ ${returnCode} -gt 0 ]]
+ then
+ echo "Conformance test failed for config: ${config}"
+ RETURN_CODE=${returnCode}
+ else
+ echo "Conformance test passed for config: ${config}"
+ fi
+done
+
+exit ${RETURN_CODE}
\ No newline at end of file
diff --git a/Bigtable/src/Table.php b/Bigtable/src/Table.php
index f0c606956b7a..f02fec509af5 100644
--- a/Bigtable/src/Table.php
+++ b/Bigtable/src/Table.php
@@ -168,7 +168,7 @@ public function mutateRows(array $rowMutations, array $options = [])
*/
public function mutateRow($rowKey, Mutations $mutations, array $options = [])
{
- list($data, $optionalArgs) = $this->splitOptionalArgs($options);
+ list($data, $optionalArgs) = $this->splitOptionalArgs($options + $this->options);
$data['table_name'] = $this->tableName;
$data['row_key'] = $rowKey;
$data['mutations'] = $mutations->toProto();
@@ -176,7 +176,6 @@ public function mutateRow($rowKey, Mutations $mutations, array $options = [])
new MutateRowRequest(),
$data
);
- $optionalArgs += $this->options;
$this->gapicClient->mutateRow($request, $optionalArgs);
}
@@ -287,7 +286,7 @@ public function readRows(array $options = [])
$rowKeys = $this->pluck('rowKeys', $options, false) ?: [];
$ranges = $this->pluck('rowRanges', $options, false) ?: [];
$filter = $this->pluck('filter', $options, false) ?: null;
- list($data, $optionalArgs) = $this->splitOptionalArgs($options, ['retrySettings']);
+ list($data, $optionalArgs) = $this->splitOptionalArgs($options + $this->options);
array_walk($ranges, function (&$range) {
$range = $this->serializer->decodeMessage(
@@ -325,7 +324,7 @@ public function readRows(array $options = [])
return new ChunkFormatter(
$this->gapicClient,
$request,
- $optionalArgs + $this->options
+ $optionalArgs
);
}
@@ -515,14 +514,14 @@ public function checkAndMutateRow($rowKey, array $options = [])
throw new \InvalidArgumentException('checkAndMutateRow must have either trueMutations or falseMutations.');
}
- list($data, $optionalArgs) = $this->splitOptionalArgs($options);
+ list($data, $optionalArgs) = $this->splitOptionalArgs($options + $this->options);
$data['table_name'] = $this->tableName;
$data['row_key'] = $rowKey;
$request = $this->serializer->decodeMessage(new CheckAndMutateRowRequest(), $data);
return $this->gapicClient->checkAndMutateRow(
$request,
- $optionalArgs + $this->options
+ $optionalArgs
)->getPredicateMatched();
}
@@ -552,7 +551,7 @@ private function mutateRowsWithEntries(array $entries, array $options = [])
return false;
};
- list($data, $optionalArgs) = $this->splitOptionalArgs($options, ['retrySettings']);
+ list($data, $optionalArgs) = $this->splitOptionalArgs($options);
$request = $this->serializer->decodeMessage(new MutateRowsRequest(), $data);
$request->setTableName($this->tableName);
@@ -631,7 +630,8 @@ private function appendPendingEntryToFailedMutations(
$rowMutationsFailedResponse[] = [
'rowKey' => $entries[$index]->getRowKey(),
'statusCode' => $statusCode,
- 'message' => $message
+ 'message' => $message,
+ 'index' => $index
];
}
}
diff --git a/Bigtable/tests/Conformance/proxy/.rr.yaml b/Bigtable/tests/Conformance/proxy/.rr.yaml
new file mode 100644
index 000000000000..f311762433c5
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/.rr.yaml
@@ -0,0 +1,30 @@
+version: "3"
+rpc:
+ listen: "tcp://127.0.0.1:6001"
+
+server:
+ command: "php worker.php"
+ relay: "pipes"
+ relay_timeout: "20s"
+
+kv:
+ memory-cache:
+ driver: memory
+ config: { }
+
+grpc:
+ listen: "tcp://127.0.0.1:9999"
+ proto: ["test_proxy.proto"]
+ max_send_msg_size: 50
+ max_recv_msg_size: 50
+ max_connection_idle: 0s
+ max_connection_age: 0s
+ max_connection_age_grace: 0s
+ max_concurrent_streams: 10
+ ping_time: 1s
+ timeout: 200s
+ pool:
+ num_workers: 5
+ max_jobs: 0
+ allocate_timeout: 60s
+ destroy_timeout: 60s
diff --git a/Bigtable/tests/Conformance/proxy/composer.json b/Bigtable/tests/Conformance/proxy/composer.json
new file mode 100644
index 000000000000..ae4051467cf9
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "google-testing/proxy-bigtable-server",
+ "description": "Proxy Bigtable Server",
+ "repositories": [
+ {
+ "type": "path",
+ "url": "../../.."
+ }
+ ],
+ "require": {
+ "google/cloud-bigtable": "*",
+ "grpc/grpc": "^1.36",
+ "spiral/roadrunner-cli": "^2.6",
+ "spiral/roadrunner-grpc": "^3.4",
+ "spiral/roadrunner-kv": "^4.3"
+ },
+ "autoload": {
+ "psr-4": {
+ "": "src"
+ }
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true
+}
diff --git a/Bigtable/tests/Conformance/proxy/ping.php b/Bigtable/tests/Conformance/proxy/ping.php
new file mode 100644
index 000000000000..1c108207549c
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/ping.php
@@ -0,0 +1,17 @@
+ \Grpc\ChannelCredentials::createInsecure(),
+]);
+
+$message = new CreateClientRequest();
+
+[$response, $status] = $client->CreateClient($message)->wait();
+
+echo $response->serializeToJsonString() . PHP_EOL;
diff --git a/Bigtable/tests/Conformance/proxy/src/GPBMetadata/Google/Bigtable/Testproxy/TestProxy.php b/Bigtable/tests/Conformance/proxy/src/GPBMetadata/Google/Bigtable/Testproxy/TestProxy.php
new file mode 100644
index 000000000000..90a9531918bb
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/GPBMetadata/Google/Bigtable/Testproxy/TestProxy.php
@@ -0,0 +1,30 @@
+internalAddGeneratedFile(
+ "\x0A\xC0 \x0A*google/bigtable/testproxy/test_proxy.proto\x12\x19google.bigtable.testproxy\x1A!google/bigtable/v2/bigtable.proto\x1A\x1Dgoogle/bigtable/v2/data.proto\x1A\x1Egoogle/protobuf/duration.proto\x1A\x17google/rpc/status.proto\"\xDA\x03\x0A\x13CreateClientRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x12\x13\x0A\x0Bdata_target\x18\x02 \x01(\x09\x12\x12\x0A\x0Aproject_id\x18\x03 \x01(\x09\x12\x13\x0A\x0Binstance_id\x18\x04 \x01(\x09\x12\x16\x0A\x0Eapp_profile_id\x18\x05 \x01(\x09\x128\x0A\x15per_operation_timeout\x18\x06 \x01(\x0B2\x19.google.protobuf.Duration\x12Q\x0A\x17optional_feature_config\x18\x07 \x01(\x0E20.google.bigtable.testproxy.OptionalFeatureConfig\x12X\x0A\x10security_options\x18\x08 \x01(\x0B2>.google.bigtable.testproxy.CreateClientRequest.SecurityOptions\x1As\x0A\x0FSecurityOptions\x12\x14\x0A\x0Caccess_token\x18\x01 \x01(\x09\x12\x0F\x0A\x07use_ssl\x18\x02 \x01(\x08\x12\x1D\x0A\x15ssl_endpoint_override\x18\x03 \x01(\x09\x12\x1A\x0A\x12ssl_root_certs_pem\x18\x04 \x01(\x09\"\x16\x0A\x14CreateClientResponse\"'\x0A\x12CloseClientRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\"\x15\x0A\x13CloseClientResponse\"(\x0A\x13RemoveClientRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\"\x16\x0A\x14RemoveClientResponse\"w\x0A\x0EReadRowRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x12\x12\x0A\x0Atable_name\x18\x04 \x01(\x09\x12\x0F\x0A\x07row_key\x18\x02 \x01(\x09\x12-\x0A\x06filter\x18\x03 \x01(\x0B2\x1D.google.bigtable.v2.RowFilter\"U\x0A\x09RowResult\x12\"\x0A\x06status\x18\x01 \x01(\x0B2\x12.google.rpc.Status\x12\$\x0A\x03row\x18\x02 \x01(\x0B2\x17.google.bigtable.v2.Row\"u\x0A\x0FReadRowsRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x124\x0A\x07request\x18\x02 \x01(\x0B2#.google.bigtable.v2.ReadRowsRequest\x12\x19\x0A\x11cancel_after_rows\x18\x03 \x01(\x05\"W\x0A\x0ARowsResult\x12\"\x0A\x06status\x18\x01 \x01(\x0B2\x12.google.rpc.Status\x12%\x0A\x04rows\x18\x02 \x03(\x0B2\x17.google.bigtable.v2.Row\"\\\x0A\x10MutateRowRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x125\x0A\x07request\x18\x02 \x01(\x0B2\$.google.bigtable.v2.MutateRowRequest\"5\x0A\x0FMutateRowResult\x12\"\x0A\x06status\x18\x01 \x01(\x0B2\x12.google.rpc.Status\"^\x0A\x11MutateRowsRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x126\x0A\x07request\x18\x02 \x01(\x0B2%.google.bigtable.v2.MutateRowsRequest\"u\x0A\x10MutateRowsResult\x12\"\x0A\x06status\x18\x01 \x01(\x0B2\x12.google.rpc.Status\x12=\x0A\x07entries\x18\x02 \x03(\x0B2,.google.bigtable.v2.MutateRowsResponse.Entry\"l\x0A\x18CheckAndMutateRowRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x12=\x0A\x07request\x18\x02 \x01(\x0B2,.google.bigtable.v2.CheckAndMutateRowRequest\"|\x0A\x17CheckAndMutateRowResult\x12\"\x0A\x06status\x18\x01 \x01(\x0B2\x12.google.rpc.Status\x12=\x0A\x06result\x18\x02 \x01(\x0B2-.google.bigtable.v2.CheckAndMutateRowResponse\"d\x0A\x14SampleRowKeysRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x129\x0A\x07request\x18\x02 \x01(\x0B2(.google.bigtable.v2.SampleRowKeysRequest\"u\x0A\x13SampleRowKeysResult\x12\"\x0A\x06status\x18\x01 \x01(\x0B2\x12.google.rpc.Status\x12:\x0A\x07samples\x18\x02 \x03(\x0B2).google.bigtable.v2.SampleRowKeysResponse\"n\x0A\x19ReadModifyWriteRowRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x12>\x0A\x07request\x18\x02 \x01(\x0B2-.google.bigtable.v2.ReadModifyWriteRowRequest\"b\x0A\x13ExecuteQueryRequest\x12\x11\x0A\x09client_id\x18\x01 \x01(\x09\x128\x0A\x07request\x18\x02 \x01(\x0B2'.google.bigtable.v2.ExecuteQueryRequest\"\xED\x01\x0A\x12ExecuteQueryResult\x12\"\x0A\x06status\x18\x01 \x01(\x0B2\x12.google.rpc.Status\x12B\x0A\x13result_set_metadata\x18\x02 \x01(\x0B2%.google.bigtable.v2.ResultSetMetadata\x12>\x0A\x08metadata\x18\x04 \x01(\x0B2,.google.bigtable.testproxy.ResultSetMetadata\x12/\x0A\x04rows\x18\x03 \x03(\x0B2!.google.bigtable.testproxy.SqlRow\"H\x0A\x11ResultSetMetadata\x123\x0A\x07columns\x18\x01 \x03(\x0B2\".google.bigtable.v2.ColumnMetadata\"3\x0A\x06SqlRow\x12)\x0A\x06values\x18\x01 \x03(\x0B2\x19.google.bigtable.v2.Value*d\x0A\x15OptionalFeatureConfig\x12#\x0A\x1FOPTIONAL_FEATURE_CONFIG_DEFAULT\x10\x00\x12&\x0A\"OPTIONAL_FEATURE_CONFIG_ENABLE_ALL\x10\x012\x95\x0A\x0A\x18CloudBigtableV2TestProxy\x12q\x0A\x0CCreateClient\x12..google.bigtable.testproxy.CreateClientRequest\x1A/.google.bigtable.testproxy.CreateClientResponse\"\x00\x12n\x0A\x0BCloseClient\x12-.google.bigtable.testproxy.CloseClientRequest\x1A..google.bigtable.testproxy.CloseClientResponse\"\x00\x12q\x0A\x0CRemoveClient\x12..google.bigtable.testproxy.RemoveClientRequest\x1A/.google.bigtable.testproxy.RemoveClientResponse\"\x00\x12\\\x0A\x07ReadRow\x12).google.bigtable.testproxy.ReadRowRequest\x1A\$.google.bigtable.testproxy.RowResult\"\x00\x12_\x0A\x08ReadRows\x12*.google.bigtable.testproxy.ReadRowsRequest\x1A%.google.bigtable.testproxy.RowsResult\"\x00\x12f\x0A\x09MutateRow\x12+.google.bigtable.testproxy.MutateRowRequest\x1A*.google.bigtable.testproxy.MutateRowResult\"\x00\x12m\x0A\x0EBulkMutateRows\x12,.google.bigtable.testproxy.MutateRowsRequest\x1A+.google.bigtable.testproxy.MutateRowsResult\"\x00\x12~\x0A\x11CheckAndMutateRow\x123.google.bigtable.testproxy.CheckAndMutateRowRequest\x1A2.google.bigtable.testproxy.CheckAndMutateRowResult\"\x00\x12r\x0A\x0DSampleRowKeys\x12/.google.bigtable.testproxy.SampleRowKeysRequest\x1A..google.bigtable.testproxy.SampleRowKeysResult\"\x00\x12r\x0A\x12ReadModifyWriteRow\x124.google.bigtable.testproxy.ReadModifyWriteRowRequest\x1A\$.google.bigtable.testproxy.RowResult\"\x00\x12o\x0A\x0CExecuteQuery\x12..google.bigtable.testproxy.ExecuteQueryRequest\x1A-.google.bigtable.testproxy.ExecuteQueryResult\"\x00\x1A4\xCAA1bigtable-test-proxy-not-accessible.googleapis.comBg\x0A#com.google.cloud.bigtable.testproxyP\x01Z>cloud.google.com/go/bigtable/testproxy/testproxypb;testproxypbb\x06proto3"
+ , true);
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CheckAndMutateRowRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CheckAndMutateRowRequest.php
new file mode 100644
index 000000000000..6d3c7792a215
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CheckAndMutateRowRequest.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.CheckAndMutateRowRequest
+ */
+class CheckAndMutateRowRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.CheckAndMutateRowRequest request = 2;
+ */
+ protected $request = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type \Google\Cloud\Bigtable\V2\CheckAndMutateRowRequest $request
+ * The raw request to the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.CheckAndMutateRowRequest request = 2;
+ * @return \Google\Cloud\Bigtable\V2\CheckAndMutateRowRequest|null
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ public function hasRequest()
+ {
+ return isset($this->request);
+ }
+
+ public function clearRequest()
+ {
+ unset($this->request);
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.CheckAndMutateRowRequest request = 2;
+ * @param \Google\Cloud\Bigtable\V2\CheckAndMutateRowRequest $var
+ * @return $this
+ */
+ public function setRequest($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\CheckAndMutateRowRequest::class);
+ $this->request = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CheckAndMutateRowResult.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CheckAndMutateRowResult.php
new file mode 100644
index 000000000000..076162568a27
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CheckAndMutateRowResult.php
@@ -0,0 +1,122 @@
+google.bigtable.testproxy.CheckAndMutateRowResult
+ */
+class CheckAndMutateRowResult extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ */
+ protected $status = null;
+ /**
+ * The raw response from the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.CheckAndMutateRowResponse result = 2;
+ */
+ protected $result = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Google\Rpc\Status $status
+ * The RPC status from the client binding.
+ * @type \Google\Cloud\Bigtable\V2\CheckAndMutateRowResponse $result
+ * The raw response from the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @return \Google\Rpc\Status|null
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function hasStatus()
+ {
+ return isset($this->status);
+ }
+
+ public function clearStatus()
+ {
+ unset($this->status);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @param \Google\Rpc\Status $var
+ * @return $this
+ */
+ public function setStatus($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Rpc\Status::class);
+ $this->status = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw response from the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.CheckAndMutateRowResponse result = 2;
+ * @return \Google\Cloud\Bigtable\V2\CheckAndMutateRowResponse|null
+ */
+ public function getResult()
+ {
+ return $this->result;
+ }
+
+ public function hasResult()
+ {
+ return isset($this->result);
+ }
+
+ public function clearResult()
+ {
+ unset($this->result);
+ }
+
+ /**
+ * The raw response from the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.CheckAndMutateRowResponse result = 2;
+ * @param \Google\Cloud\Bigtable\V2\CheckAndMutateRowResponse $var
+ * @return $this
+ */
+ public function setResult($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\CheckAndMutateRowResponse::class);
+ $this->result = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloseClientRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloseClientRequest.php
new file mode 100644
index 000000000000..1552575f2560
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloseClientRequest.php
@@ -0,0 +1,68 @@
+google.bigtable.testproxy.CloseClientRequest
+ */
+class CloseClientRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloseClientResponse.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloseClientResponse.php
new file mode 100644
index 000000000000..34deeffd6d69
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloseClientResponse.php
@@ -0,0 +1,34 @@
+google.bigtable.testproxy.CloseClientResponse
+ */
+class CloseClientResponse extends \Google\Protobuf\Internal\Message
+{
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloudBigtableV2TestProxyInterface.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloudBigtableV2TestProxyInterface.php
new file mode 100644
index 000000000000..2e96424773da
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CloudBigtableV2TestProxyInterface.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.CreateClientRequest
+ */
+class CreateClientRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * A unique ID associated with the client object to be created.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The "host:port" address of the data API endpoint (i.e. the backend being
+ * proxied to). Example: 127.0.0.1:38543. If you want to connect to a local
+ * emulator via BIGTABLE_EMULATOR_HOST environment variable, you can use
+ * "emulator" instead of "host:port" for this field.
+ *
+ * Generated from protobuf field string data_target = 2;
+ */
+ protected $data_target = '';
+ /**
+ * The project for all calls on this client.
+ *
+ * Generated from protobuf field string project_id = 3;
+ */
+ protected $project_id = '';
+ /**
+ * The instance for all calls on this client.
+ *
+ * Generated from protobuf field string instance_id = 4;
+ */
+ protected $instance_id = '';
+ /**
+ * Optional app profile for all calls on this client.
+ * Some client bindings allow specifying the app profile on a per-operation
+ * basis. We don't yet support this in the proxy API, but may in the future.
+ *
+ * Generated from protobuf field string app_profile_id = 5;
+ */
+ protected $app_profile_id = '';
+ /**
+ * If provided, a custom timeout will be set for each API call conducted by
+ * the created client. Otherwise, the default timeout from the client library
+ * will be used. Note that the override applies to all the methods.
+ *
+ * Generated from protobuf field .google.protobuf.Duration per_operation_timeout = 6;
+ */
+ protected $per_operation_timeout = null;
+ /**
+ * Optional config that dictates how the optional features should be enabled
+ * during the client creation. Please check the enum type's docstring above.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.OptionalFeatureConfig optional_feature_config = 7;
+ */
+ protected $optional_feature_config = 0;
+ /**
+ * Options to allow connecting to backends with channel and/or call
+ * credentials. This is needed internally by Cloud Bigtable's own testing
+ * frameworks.It is not necessary to support these fields for client
+ * conformance testing.
+ * WARNING: this allows the proxy to connect to a real production
+ * CBT backend with the right options, however, the proxy itself is insecure
+ * so it is not recommended to use it with real credentials or outside testing
+ * contexts.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.CreateClientRequest.SecurityOptions security_options = 8;
+ */
+ protected $security_options = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * A unique ID associated with the client object to be created.
+ * @type string $data_target
+ * The "host:port" address of the data API endpoint (i.e. the backend being
+ * proxied to). Example: 127.0.0.1:38543. If you want to connect to a local
+ * emulator via BIGTABLE_EMULATOR_HOST environment variable, you can use
+ * "emulator" instead of "host:port" for this field.
+ * @type string $project_id
+ * The project for all calls on this client.
+ * @type string $instance_id
+ * The instance for all calls on this client.
+ * @type string $app_profile_id
+ * Optional app profile for all calls on this client.
+ * Some client bindings allow specifying the app profile on a per-operation
+ * basis. We don't yet support this in the proxy API, but may in the future.
+ * @type \Google\Protobuf\Duration $per_operation_timeout
+ * If provided, a custom timeout will be set for each API call conducted by
+ * the created client. Otherwise, the default timeout from the client library
+ * will be used. Note that the override applies to all the methods.
+ * @type int $optional_feature_config
+ * Optional config that dictates how the optional features should be enabled
+ * during the client creation. Please check the enum type's docstring above.
+ * @type \Google\Bigtable\Testproxy\CreateClientRequest\SecurityOptions $security_options
+ * Options to allow connecting to backends with channel and/or call
+ * credentials. This is needed internally by Cloud Bigtable's own testing
+ * frameworks.It is not necessary to support these fields for client
+ * conformance testing.
+ * WARNING: this allows the proxy to connect to a real production
+ * CBT backend with the right options, however, the proxy itself is insecure
+ * so it is not recommended to use it with real credentials or outside testing
+ * contexts.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * A unique ID associated with the client object to be created.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * A unique ID associated with the client object to be created.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The "host:port" address of the data API endpoint (i.e. the backend being
+ * proxied to). Example: 127.0.0.1:38543. If you want to connect to a local
+ * emulator via BIGTABLE_EMULATOR_HOST environment variable, you can use
+ * "emulator" instead of "host:port" for this field.
+ *
+ * Generated from protobuf field string data_target = 2;
+ * @return string
+ */
+ public function getDataTarget()
+ {
+ return $this->data_target;
+ }
+
+ /**
+ * The "host:port" address of the data API endpoint (i.e. the backend being
+ * proxied to). Example: 127.0.0.1:38543. If you want to connect to a local
+ * emulator via BIGTABLE_EMULATOR_HOST environment variable, you can use
+ * "emulator" instead of "host:port" for this field.
+ *
+ * Generated from protobuf field string data_target = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setDataTarget($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->data_target = $var;
+
+ return $this;
+ }
+
+ /**
+ * The project for all calls on this client.
+ *
+ * Generated from protobuf field string project_id = 3;
+ * @return string
+ */
+ public function getProjectId()
+ {
+ return $this->project_id;
+ }
+
+ /**
+ * The project for all calls on this client.
+ *
+ * Generated from protobuf field string project_id = 3;
+ * @param string $var
+ * @return $this
+ */
+ public function setProjectId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->project_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The instance for all calls on this client.
+ *
+ * Generated from protobuf field string instance_id = 4;
+ * @return string
+ */
+ public function getInstanceId()
+ {
+ return $this->instance_id;
+ }
+
+ /**
+ * The instance for all calls on this client.
+ *
+ * Generated from protobuf field string instance_id = 4;
+ * @param string $var
+ * @return $this
+ */
+ public function setInstanceId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->instance_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional app profile for all calls on this client.
+ * Some client bindings allow specifying the app profile on a per-operation
+ * basis. We don't yet support this in the proxy API, but may in the future.
+ *
+ * Generated from protobuf field string app_profile_id = 5;
+ * @return string
+ */
+ public function getAppProfileId()
+ {
+ return $this->app_profile_id;
+ }
+
+ /**
+ * Optional app profile for all calls on this client.
+ * Some client bindings allow specifying the app profile on a per-operation
+ * basis. We don't yet support this in the proxy API, but may in the future.
+ *
+ * Generated from protobuf field string app_profile_id = 5;
+ * @param string $var
+ * @return $this
+ */
+ public function setAppProfileId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->app_profile_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * If provided, a custom timeout will be set for each API call conducted by
+ * the created client. Otherwise, the default timeout from the client library
+ * will be used. Note that the override applies to all the methods.
+ *
+ * Generated from protobuf field .google.protobuf.Duration per_operation_timeout = 6;
+ * @return \Google\Protobuf\Duration|null
+ */
+ public function getPerOperationTimeout()
+ {
+ return $this->per_operation_timeout;
+ }
+
+ public function hasPerOperationTimeout()
+ {
+ return isset($this->per_operation_timeout);
+ }
+
+ public function clearPerOperationTimeout()
+ {
+ unset($this->per_operation_timeout);
+ }
+
+ /**
+ * If provided, a custom timeout will be set for each API call conducted by
+ * the created client. Otherwise, the default timeout from the client library
+ * will be used. Note that the override applies to all the methods.
+ *
+ * Generated from protobuf field .google.protobuf.Duration per_operation_timeout = 6;
+ * @param \Google\Protobuf\Duration $var
+ * @return $this
+ */
+ public function setPerOperationTimeout($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class);
+ $this->per_operation_timeout = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional config that dictates how the optional features should be enabled
+ * during the client creation. Please check the enum type's docstring above.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.OptionalFeatureConfig optional_feature_config = 7;
+ * @return int
+ */
+ public function getOptionalFeatureConfig()
+ {
+ return $this->optional_feature_config;
+ }
+
+ /**
+ * Optional config that dictates how the optional features should be enabled
+ * during the client creation. Please check the enum type's docstring above.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.OptionalFeatureConfig optional_feature_config = 7;
+ * @param int $var
+ * @return $this
+ */
+ public function setOptionalFeatureConfig($var)
+ {
+ GPBUtil::checkEnum($var, \Google\Bigtable\Testproxy\OptionalFeatureConfig::class);
+ $this->optional_feature_config = $var;
+
+ return $this;
+ }
+
+ /**
+ * Options to allow connecting to backends with channel and/or call
+ * credentials. This is needed internally by Cloud Bigtable's own testing
+ * frameworks.It is not necessary to support these fields for client
+ * conformance testing.
+ * WARNING: this allows the proxy to connect to a real production
+ * CBT backend with the right options, however, the proxy itself is insecure
+ * so it is not recommended to use it with real credentials or outside testing
+ * contexts.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.CreateClientRequest.SecurityOptions security_options = 8;
+ * @return \Google\Bigtable\Testproxy\CreateClientRequest\SecurityOptions|null
+ */
+ public function getSecurityOptions()
+ {
+ return $this->security_options;
+ }
+
+ public function hasSecurityOptions()
+ {
+ return isset($this->security_options);
+ }
+
+ public function clearSecurityOptions()
+ {
+ unset($this->security_options);
+ }
+
+ /**
+ * Options to allow connecting to backends with channel and/or call
+ * credentials. This is needed internally by Cloud Bigtable's own testing
+ * frameworks.It is not necessary to support these fields for client
+ * conformance testing.
+ * WARNING: this allows the proxy to connect to a real production
+ * CBT backend with the right options, however, the proxy itself is insecure
+ * so it is not recommended to use it with real credentials or outside testing
+ * contexts.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.CreateClientRequest.SecurityOptions security_options = 8;
+ * @param \Google\Bigtable\Testproxy\CreateClientRequest\SecurityOptions $var
+ * @return $this
+ */
+ public function setSecurityOptions($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Bigtable\Testproxy\CreateClientRequest\SecurityOptions::class);
+ $this->security_options = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CreateClientRequest/SecurityOptions.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CreateClientRequest/SecurityOptions.php
new file mode 100644
index 000000000000..d5cd343672fa
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CreateClientRequest/SecurityOptions.php
@@ -0,0 +1,196 @@
+google.bigtable.testproxy.CreateClientRequest.SecurityOptions
+ */
+class SecurityOptions extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Access token to use for client credentials. If empty, the client will not
+ * use any call credentials. Certain implementations may require `use_ssl`
+ * to be set when using this.
+ *
+ * Generated from protobuf field string access_token = 1;
+ */
+ protected $access_token = '';
+ /**
+ * Whether to use SSL channel credentials when connecting to the data
+ * endpoint.
+ *
+ * Generated from protobuf field bool use_ssl = 2;
+ */
+ protected $use_ssl = false;
+ /**
+ * If using SSL channel credentials, override the SSL endpoint to match the
+ * host that is specified in the backend's certificate. Also sets the
+ * client's authority header value.
+ *
+ * Generated from protobuf field string ssl_endpoint_override = 3;
+ */
+ protected $ssl_endpoint_override = '';
+ /**
+ * PEM encoding of the server root certificates. If not set, the default
+ * root certs will be used instead. The default can be overridden via the
+ * GRPC_DEFAULT_SSL_ROOTS_FILE_PATH env var.
+ *
+ * Generated from protobuf field string ssl_root_certs_pem = 4;
+ */
+ protected $ssl_root_certs_pem = '';
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $access_token
+ * Access token to use for client credentials. If empty, the client will not
+ * use any call credentials. Certain implementations may require `use_ssl`
+ * to be set when using this.
+ * @type bool $use_ssl
+ * Whether to use SSL channel credentials when connecting to the data
+ * endpoint.
+ * @type string $ssl_endpoint_override
+ * If using SSL channel credentials, override the SSL endpoint to match the
+ * host that is specified in the backend's certificate. Also sets the
+ * client's authority header value.
+ * @type string $ssl_root_certs_pem
+ * PEM encoding of the server root certificates. If not set, the default
+ * root certs will be used instead. The default can be overridden via the
+ * GRPC_DEFAULT_SSL_ROOTS_FILE_PATH env var.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Access token to use for client credentials. If empty, the client will not
+ * use any call credentials. Certain implementations may require `use_ssl`
+ * to be set when using this.
+ *
+ * Generated from protobuf field string access_token = 1;
+ * @return string
+ */
+ public function getAccessToken()
+ {
+ return $this->access_token;
+ }
+
+ /**
+ * Access token to use for client credentials. If empty, the client will not
+ * use any call credentials. Certain implementations may require `use_ssl`
+ * to be set when using this.
+ *
+ * Generated from protobuf field string access_token = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setAccessToken($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->access_token = $var;
+
+ return $this;
+ }
+
+ /**
+ * Whether to use SSL channel credentials when connecting to the data
+ * endpoint.
+ *
+ * Generated from protobuf field bool use_ssl = 2;
+ * @return bool
+ */
+ public function getUseSsl()
+ {
+ return $this->use_ssl;
+ }
+
+ /**
+ * Whether to use SSL channel credentials when connecting to the data
+ * endpoint.
+ *
+ * Generated from protobuf field bool use_ssl = 2;
+ * @param bool $var
+ * @return $this
+ */
+ public function setUseSsl($var)
+ {
+ GPBUtil::checkBool($var);
+ $this->use_ssl = $var;
+
+ return $this;
+ }
+
+ /**
+ * If using SSL channel credentials, override the SSL endpoint to match the
+ * host that is specified in the backend's certificate. Also sets the
+ * client's authority header value.
+ *
+ * Generated from protobuf field string ssl_endpoint_override = 3;
+ * @return string
+ */
+ public function getSslEndpointOverride()
+ {
+ return $this->ssl_endpoint_override;
+ }
+
+ /**
+ * If using SSL channel credentials, override the SSL endpoint to match the
+ * host that is specified in the backend's certificate. Also sets the
+ * client's authority header value.
+ *
+ * Generated from protobuf field string ssl_endpoint_override = 3;
+ * @param string $var
+ * @return $this
+ */
+ public function setSslEndpointOverride($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->ssl_endpoint_override = $var;
+
+ return $this;
+ }
+
+ /**
+ * PEM encoding of the server root certificates. If not set, the default
+ * root certs will be used instead. The default can be overridden via the
+ * GRPC_DEFAULT_SSL_ROOTS_FILE_PATH env var.
+ *
+ * Generated from protobuf field string ssl_root_certs_pem = 4;
+ * @return string
+ */
+ public function getSslRootCertsPem()
+ {
+ return $this->ssl_root_certs_pem;
+ }
+
+ /**
+ * PEM encoding of the server root certificates. If not set, the default
+ * root certs will be used instead. The default can be overridden via the
+ * GRPC_DEFAULT_SSL_ROOTS_FILE_PATH env var.
+ *
+ * Generated from protobuf field string ssl_root_certs_pem = 4;
+ * @param string $var
+ * @return $this
+ */
+ public function setSslRootCertsPem($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->ssl_root_certs_pem = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CreateClientResponse.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CreateClientResponse.php
new file mode 100644
index 000000000000..4b8c558f74d3
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/CreateClientResponse.php
@@ -0,0 +1,34 @@
+google.bigtable.testproxy.CreateClientResponse
+ */
+class CreateClientResponse extends \Google\Protobuf\Internal\Message
+{
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ExecuteQueryRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ExecuteQueryRequest.php
new file mode 100644
index 000000000000..daf5025f0fb1
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ExecuteQueryRequest.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.ExecuteQueryRequest
+ */
+class ExecuteQueryRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ExecuteQueryRequest request = 2;
+ */
+ protected $request = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type \Google\Cloud\Bigtable\V2\ExecuteQueryRequest $request
+ * The raw request to the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ExecuteQueryRequest request = 2;
+ * @return \Google\Cloud\Bigtable\V2\ExecuteQueryRequest|null
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ public function hasRequest()
+ {
+ return isset($this->request);
+ }
+
+ public function clearRequest()
+ {
+ unset($this->request);
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ExecuteQueryRequest request = 2;
+ * @param \Google\Cloud\Bigtable\V2\ExecuteQueryRequest $var
+ * @return $this
+ */
+ public function setRequest($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\ExecuteQueryRequest::class);
+ $this->request = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ExecuteQueryResult.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ExecuteQueryResult.php
new file mode 100644
index 000000000000..25b970089fff
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ExecuteQueryResult.php
@@ -0,0 +1,200 @@
+google.bigtable.testproxy.ExecuteQueryResult
+ */
+class ExecuteQueryResult extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ */
+ protected $status = null;
+ /**
+ * deprecated
+ *
+ * Generated from protobuf field .google.bigtable.v2.ResultSetMetadata result_set_metadata = 2;
+ */
+ protected $result_set_metadata = null;
+ /**
+ * Name and type information for the query result.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.ResultSetMetadata metadata = 4;
+ */
+ protected $metadata = null;
+ /**
+ * Encoded version of the ResultSet. Should not contain type information.
+ *
+ * Generated from protobuf field repeated .google.bigtable.testproxy.SqlRow rows = 3;
+ */
+ private $rows;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Google\Rpc\Status $status
+ * The RPC status from the client binding.
+ * @type \Google\Cloud\Bigtable\V2\ResultSetMetadata $result_set_metadata
+ * deprecated
+ * @type \Google\Bigtable\Testproxy\ResultSetMetadata $metadata
+ * Name and type information for the query result.
+ * @type array<\Google\Bigtable\Testproxy\SqlRow>|\Google\Protobuf\Internal\RepeatedField $rows
+ * Encoded version of the ResultSet. Should not contain type information.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @return \Google\Rpc\Status|null
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function hasStatus()
+ {
+ return isset($this->status);
+ }
+
+ public function clearStatus()
+ {
+ unset($this->status);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @param \Google\Rpc\Status $var
+ * @return $this
+ */
+ public function setStatus($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Rpc\Status::class);
+ $this->status = $var;
+
+ return $this;
+ }
+
+ /**
+ * deprecated
+ *
+ * Generated from protobuf field .google.bigtable.v2.ResultSetMetadata result_set_metadata = 2;
+ * @return \Google\Cloud\Bigtable\V2\ResultSetMetadata|null
+ */
+ public function getResultSetMetadata()
+ {
+ return $this->result_set_metadata;
+ }
+
+ public function hasResultSetMetadata()
+ {
+ return isset($this->result_set_metadata);
+ }
+
+ public function clearResultSetMetadata()
+ {
+ unset($this->result_set_metadata);
+ }
+
+ /**
+ * deprecated
+ *
+ * Generated from protobuf field .google.bigtable.v2.ResultSetMetadata result_set_metadata = 2;
+ * @param \Google\Cloud\Bigtable\V2\ResultSetMetadata $var
+ * @return $this
+ */
+ public function setResultSetMetadata($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\ResultSetMetadata::class);
+ $this->result_set_metadata = $var;
+
+ return $this;
+ }
+
+ /**
+ * Name and type information for the query result.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.ResultSetMetadata metadata = 4;
+ * @return \Google\Bigtable\Testproxy\ResultSetMetadata|null
+ */
+ public function getMetadata()
+ {
+ return $this->metadata;
+ }
+
+ public function hasMetadata()
+ {
+ return isset($this->metadata);
+ }
+
+ public function clearMetadata()
+ {
+ unset($this->metadata);
+ }
+
+ /**
+ * Name and type information for the query result.
+ *
+ * Generated from protobuf field .google.bigtable.testproxy.ResultSetMetadata metadata = 4;
+ * @param \Google\Bigtable\Testproxy\ResultSetMetadata $var
+ * @return $this
+ */
+ public function setMetadata($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Bigtable\Testproxy\ResultSetMetadata::class);
+ $this->metadata = $var;
+
+ return $this;
+ }
+
+ /**
+ * Encoded version of the ResultSet. Should not contain type information.
+ *
+ * Generated from protobuf field repeated .google.bigtable.testproxy.SqlRow rows = 3;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getRows()
+ {
+ return $this->rows;
+ }
+
+ /**
+ * Encoded version of the ResultSet. Should not contain type information.
+ *
+ * Generated from protobuf field repeated .google.bigtable.testproxy.SqlRow rows = 3;
+ * @param array<\Google\Bigtable\Testproxy\SqlRow>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setRows($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Bigtable\Testproxy\SqlRow::class);
+ $this->rows = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowRequest.php
new file mode 100644
index 000000000000..6498e8e93d9e
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowRequest.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.MutateRowRequest
+ */
+class MutateRowRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.MutateRowRequest request = 2;
+ */
+ protected $request = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type \Google\Cloud\Bigtable\V2\MutateRowRequest $request
+ * The raw request to the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.MutateRowRequest request = 2;
+ * @return \Google\Cloud\Bigtable\V2\MutateRowRequest|null
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ public function hasRequest()
+ {
+ return isset($this->request);
+ }
+
+ public function clearRequest()
+ {
+ unset($this->request);
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.MutateRowRequest request = 2;
+ * @param \Google\Cloud\Bigtable\V2\MutateRowRequest $var
+ * @return $this
+ */
+ public function setRequest($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\MutateRowRequest::class);
+ $this->request = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowResult.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowResult.php
new file mode 100644
index 000000000000..e4a51de8b52d
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowResult.php
@@ -0,0 +1,78 @@
+google.bigtable.testproxy.MutateRowResult
+ */
+class MutateRowResult extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ */
+ protected $status = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Google\Rpc\Status $status
+ * The RPC status from the client binding.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @return \Google\Rpc\Status|null
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function hasStatus()
+ {
+ return isset($this->status);
+ }
+
+ public function clearStatus()
+ {
+ unset($this->status);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @param \Google\Rpc\Status $var
+ * @return $this
+ */
+ public function setStatus($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Rpc\Status::class);
+ $this->status = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowsRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowsRequest.php
new file mode 100644
index 000000000000..55ac466512c3
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowsRequest.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.MutateRowsRequest
+ */
+class MutateRowsRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.MutateRowsRequest request = 2;
+ */
+ protected $request = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type \Google\Cloud\Bigtable\V2\MutateRowsRequest $request
+ * The raw request to the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.MutateRowsRequest request = 2;
+ * @return \Google\Cloud\Bigtable\V2\MutateRowsRequest|null
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ public function hasRequest()
+ {
+ return isset($this->request);
+ }
+
+ public function clearRequest()
+ {
+ unset($this->request);
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.MutateRowsRequest request = 2;
+ * @param \Google\Cloud\Bigtable\V2\MutateRowsRequest $var
+ * @return $this
+ */
+ public function setRequest($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\MutateRowsRequest::class);
+ $this->request = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowsResult.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowsResult.php
new file mode 100644
index 000000000000..6755348e3c4c
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/MutateRowsResult.php
@@ -0,0 +1,116 @@
+google.bigtable.testproxy.MutateRowsResult
+ */
+class MutateRowsResult extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The RPC status from the client binding, corresponding to the
+ * whole operation.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ */
+ protected $status = null;
+ /**
+ * The results corresponding to the failed rows.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.MutateRowsResponse.Entry entries = 2;
+ */
+ private $entries;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Google\Rpc\Status $status
+ * The RPC status from the client binding, corresponding to the
+ * whole operation.
+ * @type array<\Google\Cloud\Bigtable\V2\MutateRowsResponse\Entry>|\Google\Protobuf\Internal\RepeatedField $entries
+ * The results corresponding to the failed rows.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The RPC status from the client binding, corresponding to the
+ * whole operation.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @return \Google\Rpc\Status|null
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function hasStatus()
+ {
+ return isset($this->status);
+ }
+
+ public function clearStatus()
+ {
+ unset($this->status);
+ }
+
+ /**
+ * The RPC status from the client binding, corresponding to the
+ * whole operation.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @param \Google\Rpc\Status $var
+ * @return $this
+ */
+ public function setStatus($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Rpc\Status::class);
+ $this->status = $var;
+
+ return $this;
+ }
+
+ /**
+ * The results corresponding to the failed rows.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.MutateRowsResponse.Entry entries = 2;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getEntries()
+ {
+ return $this->entries;
+ }
+
+ /**
+ * The results corresponding to the failed rows.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.MutateRowsResponse.Entry entries = 2;
+ * @param array<\Google\Cloud\Bigtable\V2\MutateRowsResponse\Entry>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setEntries($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Bigtable\V2\MutateRowsResponse\Entry::class);
+ $this->entries = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/OptionalFeatureConfig.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/OptionalFeatureConfig.php
new file mode 100644
index 000000000000..bc2d13c74aa9
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/OptionalFeatureConfig.php
@@ -0,0 +1,54 @@
+google.bigtable.testproxy.OptionalFeatureConfig
+ */
+class OptionalFeatureConfig
+{
+ /**
+ * Generated from protobuf enum OPTIONAL_FEATURE_CONFIG_DEFAULT = 0;
+ */
+ const OPTIONAL_FEATURE_CONFIG_DEFAULT = 0;
+ /**
+ * Generated from protobuf enum OPTIONAL_FEATURE_CONFIG_ENABLE_ALL = 1;
+ */
+ const OPTIONAL_FEATURE_CONFIG_ENABLE_ALL = 1;
+
+ private static $valueToName = [
+ self::OPTIONAL_FEATURE_CONFIG_DEFAULT => 'OPTIONAL_FEATURE_CONFIG_DEFAULT',
+ self::OPTIONAL_FEATURE_CONFIG_ENABLE_ALL => 'OPTIONAL_FEATURE_CONFIG_ENABLE_ALL',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadModifyWriteRowRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadModifyWriteRowRequest.php
new file mode 100644
index 000000000000..d7f1e97201fb
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadModifyWriteRowRequest.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.ReadModifyWriteRowRequest
+ */
+class ReadModifyWriteRowRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ReadModifyWriteRowRequest request = 2;
+ */
+ protected $request = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type \Google\Cloud\Bigtable\V2\ReadModifyWriteRowRequest $request
+ * The raw request to the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ReadModifyWriteRowRequest request = 2;
+ * @return \Google\Cloud\Bigtable\V2\ReadModifyWriteRowRequest|null
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ public function hasRequest()
+ {
+ return isset($this->request);
+ }
+
+ public function clearRequest()
+ {
+ unset($this->request);
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ReadModifyWriteRowRequest request = 2;
+ * @param \Google\Cloud\Bigtable\V2\ReadModifyWriteRowRequest $var
+ * @return $this
+ */
+ public function setRequest($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\ReadModifyWriteRowRequest::class);
+ $this->request = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadRowRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadRowRequest.php
new file mode 100644
index 000000000000..253ebb7de17d
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadRowRequest.php
@@ -0,0 +1,188 @@
+google.bigtable.testproxy.ReadRowRequest
+ */
+class ReadRowRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The unique name of the table from which to read the row.
+ * Values are of the form
+ * `projects//instances//tables/`.
+ *
+ * Generated from protobuf field string table_name = 4;
+ */
+ protected $table_name = '';
+ /**
+ * The row key of the target row.
+ *
+ * Generated from protobuf field string row_key = 2;
+ */
+ protected $row_key = '';
+ /**
+ * The row filter to be applied to the target row.
+ *
+ * Generated from protobuf field .google.bigtable.v2.RowFilter filter = 3;
+ */
+ protected $filter = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type string $table_name
+ * The unique name of the table from which to read the row.
+ * Values are of the form
+ * `projects//instances//tables/`.
+ * @type string $row_key
+ * The row key of the target row.
+ * @type \Google\Cloud\Bigtable\V2\RowFilter $filter
+ * The row filter to be applied to the target row.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The unique name of the table from which to read the row.
+ * Values are of the form
+ * `projects//instances//tables/`.
+ *
+ * Generated from protobuf field string table_name = 4;
+ * @return string
+ */
+ public function getTableName()
+ {
+ return $this->table_name;
+ }
+
+ /**
+ * The unique name of the table from which to read the row.
+ * Values are of the form
+ * `projects//instances//tables/`.
+ *
+ * Generated from protobuf field string table_name = 4;
+ * @param string $var
+ * @return $this
+ */
+ public function setTableName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->table_name = $var;
+
+ return $this;
+ }
+
+ /**
+ * The row key of the target row.
+ *
+ * Generated from protobuf field string row_key = 2;
+ * @return string
+ */
+ public function getRowKey()
+ {
+ return $this->row_key;
+ }
+
+ /**
+ * The row key of the target row.
+ *
+ * Generated from protobuf field string row_key = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setRowKey($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->row_key = $var;
+
+ return $this;
+ }
+
+ /**
+ * The row filter to be applied to the target row.
+ *
+ * Generated from protobuf field .google.bigtable.v2.RowFilter filter = 3;
+ * @return \Google\Cloud\Bigtable\V2\RowFilter|null
+ */
+ public function getFilter()
+ {
+ return $this->filter;
+ }
+
+ public function hasFilter()
+ {
+ return isset($this->filter);
+ }
+
+ public function clearFilter()
+ {
+ unset($this->filter);
+ }
+
+ /**
+ * The row filter to be applied to the target row.
+ *
+ * Generated from protobuf field .google.bigtable.v2.RowFilter filter = 3;
+ * @param \Google\Cloud\Bigtable\V2\RowFilter $var
+ * @return $this
+ */
+ public function setFilter($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\RowFilter::class);
+ $this->filter = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadRowsRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadRowsRequest.php
new file mode 100644
index 000000000000..3f9d163c796d
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ReadRowsRequest.php
@@ -0,0 +1,150 @@
+google.bigtable.testproxy.ReadRowsRequest
+ */
+class ReadRowsRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ReadRowsRequest request = 2;
+ */
+ protected $request = null;
+ /**
+ * The streaming read can be canceled before all items are seen.
+ * Has no effect if non-positive.
+ *
+ * Generated from protobuf field int32 cancel_after_rows = 3;
+ */
+ protected $cancel_after_rows = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type \Google\Cloud\Bigtable\V2\ReadRowsRequest $request
+ * The raw request to the Bigtable server.
+ * @type int $cancel_after_rows
+ * The streaming read can be canceled before all items are seen.
+ * Has no effect if non-positive.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ReadRowsRequest request = 2;
+ * @return \Google\Cloud\Bigtable\V2\ReadRowsRequest|null
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ public function hasRequest()
+ {
+ return isset($this->request);
+ }
+
+ public function clearRequest()
+ {
+ unset($this->request);
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.ReadRowsRequest request = 2;
+ * @param \Google\Cloud\Bigtable\V2\ReadRowsRequest $var
+ * @return $this
+ */
+ public function setRequest($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\ReadRowsRequest::class);
+ $this->request = $var;
+
+ return $this;
+ }
+
+ /**
+ * The streaming read can be canceled before all items are seen.
+ * Has no effect if non-positive.
+ *
+ * Generated from protobuf field int32 cancel_after_rows = 3;
+ * @return int
+ */
+ public function getCancelAfterRows()
+ {
+ return $this->cancel_after_rows;
+ }
+
+ /**
+ * The streaming read can be canceled before all items are seen.
+ * Has no effect if non-positive.
+ *
+ * Generated from protobuf field int32 cancel_after_rows = 3;
+ * @param int $var
+ * @return $this
+ */
+ public function setCancelAfterRows($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->cancel_after_rows = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RemoveClientRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RemoveClientRequest.php
new file mode 100644
index 000000000000..ee50fd66275f
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RemoveClientRequest.php
@@ -0,0 +1,68 @@
+google.bigtable.testproxy.RemoveClientRequest
+ */
+class RemoveClientRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RemoveClientResponse.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RemoveClientResponse.php
new file mode 100644
index 000000000000..38e7b91aaebb
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RemoveClientResponse.php
@@ -0,0 +1,34 @@
+google.bigtable.testproxy.RemoveClientResponse
+ */
+class RemoveClientResponse extends \Google\Protobuf\Internal\Message
+{
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ResultSetMetadata.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ResultSetMetadata.php
new file mode 100644
index 000000000000..e98ee5da55ff
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/ResultSetMetadata.php
@@ -0,0 +1,68 @@
+google.bigtable.testproxy.ResultSetMetadata
+ */
+class ResultSetMetadata extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Column metadata for each column inthe query result.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.ColumnMetadata columns = 1;
+ */
+ private $columns;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type array<\Google\Cloud\Bigtable\V2\ColumnMetadata>|\Google\Protobuf\Internal\RepeatedField $columns
+ * Column metadata for each column inthe query result.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Column metadata for each column inthe query result.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.ColumnMetadata columns = 1;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getColumns()
+ {
+ return $this->columns;
+ }
+
+ /**
+ * Column metadata for each column inthe query result.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.ColumnMetadata columns = 1;
+ * @param array<\Google\Cloud\Bigtable\V2\ColumnMetadata>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setColumns($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Bigtable\V2\ColumnMetadata::class);
+ $this->columns = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RowResult.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RowResult.php
new file mode 100644
index 000000000000..eb78ceb04c44
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RowResult.php
@@ -0,0 +1,123 @@
+google.bigtable.testproxy.RowResult
+ */
+class RowResult extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ */
+ protected $status = null;
+ /**
+ * The contents of a single row.
+ *
+ * Generated from protobuf field .google.bigtable.v2.Row row = 2;
+ */
+ protected $row = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Google\Rpc\Status $status
+ * The RPC status from the client binding.
+ * @type \Google\Cloud\Bigtable\V2\Row $row
+ * The contents of a single row.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @return \Google\Rpc\Status|null
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function hasStatus()
+ {
+ return isset($this->status);
+ }
+
+ public function clearStatus()
+ {
+ unset($this->status);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @param \Google\Rpc\Status $var
+ * @return $this
+ */
+ public function setStatus($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Rpc\Status::class);
+ $this->status = $var;
+
+ return $this;
+ }
+
+ /**
+ * The contents of a single row.
+ *
+ * Generated from protobuf field .google.bigtable.v2.Row row = 2;
+ * @return \Google\Cloud\Bigtable\V2\Row|null
+ */
+ public function getRow()
+ {
+ return $this->row;
+ }
+
+ public function hasRow()
+ {
+ return isset($this->row);
+ }
+
+ public function clearRow()
+ {
+ unset($this->row);
+ }
+
+ /**
+ * The contents of a single row.
+ *
+ * Generated from protobuf field .google.bigtable.v2.Row row = 2;
+ * @param \Google\Cloud\Bigtable\V2\Row $var
+ * @return $this
+ */
+ public function setRow($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\Row::class);
+ $this->row = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RowsResult.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RowsResult.php
new file mode 100644
index 000000000000..65fea315a273
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/RowsResult.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.RowsResult
+ */
+class RowsResult extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ */
+ protected $status = null;
+ /**
+ * The contents of rows.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.Row rows = 2;
+ */
+ private $rows;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Google\Rpc\Status $status
+ * The RPC status from the client binding.
+ * @type array<\Google\Cloud\Bigtable\V2\Row>|\Google\Protobuf\Internal\RepeatedField $rows
+ * The contents of rows.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @return \Google\Rpc\Status|null
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function hasStatus()
+ {
+ return isset($this->status);
+ }
+
+ public function clearStatus()
+ {
+ unset($this->status);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @param \Google\Rpc\Status $var
+ * @return $this
+ */
+ public function setStatus($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Rpc\Status::class);
+ $this->status = $var;
+
+ return $this;
+ }
+
+ /**
+ * The contents of rows.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.Row rows = 2;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getRows()
+ {
+ return $this->rows;
+ }
+
+ /**
+ * The contents of rows.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.Row rows = 2;
+ * @param array<\Google\Cloud\Bigtable\V2\Row>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setRows($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Bigtable\V2\Row::class);
+ $this->rows = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SampleRowKeysRequest.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SampleRowKeysRequest.php
new file mode 100644
index 000000000000..7beb30faccd4
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SampleRowKeysRequest.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.SampleRowKeysRequest
+ */
+class SampleRowKeysRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ */
+ protected $client_id = '';
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.SampleRowKeysRequest request = 2;
+ */
+ protected $request = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $client_id
+ * The ID of the target client object.
+ * @type \Google\Cloud\Bigtable\V2\SampleRowKeysRequest $request
+ * The raw request to the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @return string
+ */
+ public function getClientId()
+ {
+ return $this->client_id;
+ }
+
+ /**
+ * The ID of the target client object.
+ *
+ * Generated from protobuf field string client_id = 1;
+ * @param string $var
+ * @return $this
+ */
+ public function setClientId($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->client_id = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.SampleRowKeysRequest request = 2;
+ * @return \Google\Cloud\Bigtable\V2\SampleRowKeysRequest|null
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ public function hasRequest()
+ {
+ return isset($this->request);
+ }
+
+ public function clearRequest()
+ {
+ unset($this->request);
+ }
+
+ /**
+ * The raw request to the Bigtable server.
+ *
+ * Generated from protobuf field .google.bigtable.v2.SampleRowKeysRequest request = 2;
+ * @param \Google\Cloud\Bigtable\V2\SampleRowKeysRequest $var
+ * @return $this
+ */
+ public function setRequest($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Cloud\Bigtable\V2\SampleRowKeysRequest::class);
+ $this->request = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SampleRowKeysResult.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SampleRowKeysResult.php
new file mode 100644
index 000000000000..f1d27a3d78bd
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SampleRowKeysResult.php
@@ -0,0 +1,112 @@
+google.bigtable.testproxy.SampleRowKeysResult
+ */
+class SampleRowKeysResult extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ */
+ protected $status = null;
+ /**
+ * The raw responses from the Bigtable server.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.SampleRowKeysResponse samples = 2;
+ */
+ private $samples;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type \Google\Rpc\Status $status
+ * The RPC status from the client binding.
+ * @type array<\Google\Cloud\Bigtable\V2\SampleRowKeysResponse>|\Google\Protobuf\Internal\RepeatedField $samples
+ * The raw responses from the Bigtable server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @return \Google\Rpc\Status|null
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function hasStatus()
+ {
+ return isset($this->status);
+ }
+
+ public function clearStatus()
+ {
+ unset($this->status);
+ }
+
+ /**
+ * The RPC status from the client binding.
+ *
+ * Generated from protobuf field .google.rpc.Status status = 1;
+ * @param \Google\Rpc\Status $var
+ * @return $this
+ */
+ public function setStatus($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Rpc\Status::class);
+ $this->status = $var;
+
+ return $this;
+ }
+
+ /**
+ * The raw responses from the Bigtable server.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.SampleRowKeysResponse samples = 2;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getSamples()
+ {
+ return $this->samples;
+ }
+
+ /**
+ * The raw responses from the Bigtable server.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.SampleRowKeysResponse samples = 2;
+ * @param array<\Google\Cloud\Bigtable\V2\SampleRowKeysResponse>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setSamples($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Bigtable\V2\SampleRowKeysResponse::class);
+ $this->samples = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SqlRow.php b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SqlRow.php
new file mode 100644
index 000000000000..0c24db3ddb75
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Bigtable/Testproxy/SqlRow.php
@@ -0,0 +1,68 @@
+google.bigtable.testproxy.SqlRow
+ */
+class SqlRow extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Columnar values returned by the query.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.Value values = 1;
+ */
+ private $values;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type array<\Google\Cloud\Bigtable\V2\Value>|\Google\Protobuf\Internal\RepeatedField $values
+ * Columnar values returned by the query.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Bigtable\Testproxy\TestProxy::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Columnar values returned by the query.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.Value values = 1;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getValues()
+ {
+ return $this->values;
+ }
+
+ /**
+ * Columnar values returned by the query.
+ *
+ * Generated from protobuf field repeated .google.bigtable.v2.Value values = 1;
+ * @param array<\Google\Cloud\Bigtable\V2\Value>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setValues($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Bigtable\V2\Value::class);
+ $this->values = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/Bigtable/tests/Conformance/proxy/src/Google/Cloud/Bigtable/V2/BigtableInterface.php b/Bigtable/tests/Conformance/proxy/src/Google/Cloud/Bigtable/V2/BigtableInterface.php
new file mode 100644
index 000000000000..70de793d2ce0
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/Google/Cloud/Bigtable/V2/BigtableInterface.php
@@ -0,0 +1,103 @@
+_simpleRequest(
+ '/google.bigtable.testproxy.CloudBigtableV2TestProxy/CreateClient',
+ $message,
+ [CreateClientResponse::class, 'decode'],
+ $metadata,
+ $options
+ );
+ }
+}
diff --git a/Bigtable/tests/Conformance/proxy/src/ProxyService.php b/Bigtable/tests/Conformance/proxy/src/ProxyService.php
new file mode 100644
index 000000000000..0409f6107aa3
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/src/ProxyService.php
@@ -0,0 +1,415 @@
+serializer = new Serializer();
+
+ // create a log channel
+ $this->logger = new Logger('name');
+ $this->logger->pushHandler(new StreamHandler('php://stderr'), Level::Debug);
+
+ // create a shared cache between workers
+ // Manual configuration
+ $rpc = RPC::create('tcp://127.0.0.1:6001');
+ $factory = new Factory($rpc);
+
+ $this->cache = $factory->select('memory-cache');
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param CreateClientRequest $in
+ * @return CreateClientResponse
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function CreateClient(GRPC\ContextInterface $ctx, Testproxy\CreateClientRequest $in): Testproxy\CreateClientResponse
+ {
+ $this->logger->debug($in->serializeToJsonString());
+
+ $this->cache->set($in->getClientId(), $in);
+
+ return new Testproxy\CreateClientResponse();
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param CloseClientRequest $in
+ * @return CloseClientResponse
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function CloseClient(GRPC\ContextInterface $ctx, Testproxy\CloseClientRequest $in): Testproxy\CloseClientResponse
+ {
+ $this->getClientAndConfig($in->getClientId());
+
+ // Because our caching cannot store open channels, we implement a workaround here to close
+ // the client when its retrieved from the cache.
+ $this->cache->set($in->getClientId() . '-closed', true);
+
+ return new Testproxy\CloseClientResponse();
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param RemoveClientRequest $in
+ * @return RemoveClientResponse
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function RemoveClient(GRPC\ContextInterface $ctx, Testproxy\RemoveClientRequest $in): Testproxy\RemoveClientResponse
+ {
+ $this->cache->delete($in->getClientId());
+ $this->cache->delete($in->getClientId() . '-closed');
+
+ return new Testproxy\RemoveClientResponse();
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param ReadRowRequest $in
+ * @return RowResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function ReadRow(GRPC\ContextInterface $ctx, Testproxy\ReadRowRequest $in): Testproxy\RowResult
+ {
+ [$client, $config] = $this->getClientAndConfig($in->getClientId());
+
+ $tableName = BigtableClient::tableName($config->getProjectId(), $config->getInstanceId(), $in->getTableName());
+ $request = new ReadRowsRequest([
+ 'table_name' => $tableName,
+ 'filter' => $in->getFilter(),
+ 'app_profile_id' => $config->getProfileId(),
+ 'rows' => $this->serializer->decodeMessage(
+ new RowSet(),
+ ['rowKeys' => [$in->getRowKey()]],
+ ),
+ ]);
+ $chunkFormatter = new ChunkFormatter($client, $request, [
+ 'timeoutMillis' => $this->getTimeoutMillis($config->getPerOperationTimeout()),
+ ]);
+ $out = new Testproxy\RowResult();
+ foreach ($chunkFormatter->readAll() as $row) {
+ $row = $this->serializer->decodeMessage(new Row(), $row);
+ $out->setRow($row);
+ break;
+ }
+
+ return $out;
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param ReadRowsRequest $in
+ * @return RowsResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function ReadRows(GRPC\ContextInterface $ctx, Testproxy\ReadRowsRequest $in): Testproxy\RowsResult
+ {
+ [$client, $config] = $this->getClientAndConfig($in->getClientId());
+
+ $request = $in->getRequest();
+ $chunkFormatter = new ChunkFormatter($client, $request, [
+ 'timeoutMillis' => $this->getTimeoutMillis($config->getPerOperationTimeout()),
+ ]);
+ $rows = [];
+ $i = 0;
+ foreach ($chunkFormatter->readAll() as $row) {
+ if ($i++ >= $in->getCancelAfterRows()) {
+ break;
+ }
+ $rows[] = $this->serializer->decodeMessage(new Row(), $row);
+ }
+ $out = new Testproxy\RowsResult(['rows' => $rows]);
+
+ return $out;
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param MutateRowRequest $in
+ * @return MutateRowResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function MutateRow(GRPC\ContextInterface $ctx, Testproxy\MutateRowRequest $in): Testproxy\MutateRowResult
+ {
+ $this->logger->debug($in->serializeToJsonString());
+
+ $out = new Testproxy\MutateRowResult();
+
+ [$client, $config] = $this->getClientAndConfig($in->getClientId());
+
+ if (!$client) {
+ // This is a workaround to simulate when the client is closed.
+ return $out->setStatus(new Status([
+ 'code' => 1,
+ 'message' => 'Client is closed',
+ ]));
+ }
+
+ $request = $in->getRequest();
+ $parts = BigtableGapicClient::parseName($request->getTableName());
+ $table = $client->table($parts['instance'], $parts['table'], [
+ 'appProfileId' => $config->getAppProfileId(),
+ ]);
+
+ try {
+ $table->mutateRow(
+ $request->getRowKey(),
+ $this->protoToMutations($request->getMutations()),
+ ['timeoutMillis' => $this->getTimeoutMillis($config->getPerOperationTimeout())],
+ );
+ } catch (\Google\ApiCore\ApiException $e) {
+ return $out->setStatus(new Status([
+ 'code' => $e->getCode(),
+ 'message' => $e->getMessage(),
+ ]));
+ }
+
+ return $out;
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param MutateRowsRequest $in
+ * @return MutateRowsResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function BulkMutateRows(GRPC\ContextInterface $ctx, Testproxy\MutateRowsRequest $in): Testproxy\MutateRowsResult
+ {
+ $this->logger->debug($in->serializeToJsonString());
+
+ $out = new Testproxy\MutateRowsResult();
+
+ [$client, $config] = $this->getClientAndConfig($in->getClientId());
+
+ if (!$client) {
+ // This is a workaround to simulate when the client is closed.
+ return $out->setStatus(new Status([
+ 'code' => 1,
+ 'message' => 'Client is closed',
+ ]));
+ }
+
+ $request = $in->getRequest();
+ $parts = BigtableGapicClient::parseName($request->getTableName());
+ $table = $client->table($parts['instance'], $parts['table'], [
+ 'appProfileId' => $config->getAppProfileId(),
+ ]);
+
+ $mutations = [];
+ foreach ($request->getEntries() as $entry) {
+ $mutations[$entry->getRowKey()] = $this->protoToMutations($entry->getMutations());
+ }
+
+ try {
+ $stream = $table->mutateRows($mutations, [
+ 'timeoutMillis' => $this->getTimeoutMillis($config->getPerOperationTimeout())
+ ]);
+ } catch (BigtableDataOperationException $e) {
+ var_dump($e);
+ $failedEntries = [];
+ foreach ($e->getMetadata() as $metadata) {
+ $status = new Status([
+ 'code' => $metadata['statusCode'],
+ 'message' => $metadata['message'],
+ ]);
+ $failedEntries[] = new Entry([
+ 'index' => (int) $metadata['index'],
+ 'status' => $status,
+ ]);
+ }
+ return $out->setEntries($failedEntries);
+ } catch (\Google\ApiCore\ApiException $e) {
+ var_dump($e);
+ return $out->setStatus(new Status([
+ 'code' => $e->getCode(),
+ 'message' => $e->getMessage(),
+ ]));
+ }
+ echo "HERE";
+
+ return $out;
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param CheckAndMutateRowRequest $in
+ * @return CheckAndMutateRowResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function CheckAndMutateRow(GRPC\ContextInterface $ctx, Testproxy\CheckAndMutateRowRequest $in): Testproxy\CheckAndMutateRowResult
+ {
+ $this->logger->debug($in->serializeToJsonString());
+
+ $out = new Testproxy\CheckAndMutateRowResult();
+
+ [$client, $config] = $this->getClientAndConfig($in->getClientId());
+
+ if (!$client) {
+ // This is a workaround to simulate when the client is closed.
+ return $out->setStatus(new Status([
+ 'code' => 1,
+ 'message' => 'Client is closed',
+ ]));
+ }
+
+ $request = $in->getRequest();
+ $parts = BigtableGapicClient::parseName($request->getTableName());
+ $table = $client->table($parts['instance'], $parts['table'], [
+ 'appProfileId' => $config->getAppProfileId(),
+ ]);
+
+ try {
+ $predicateMatched = $table->checkAndMutateRow($request->getRowKey(), [
+ 'trueMutations' => $this->protoToMutations($request->getTrueMutations()),
+ 'falseMutations' => $this->protoToMutations($request->getFalseMutations()),
+ 'timeoutMillis' => $this->getTimeoutMillis($config->getPerOperationTimeout()),
+ ]);
+ } catch (\Google\ApiCore\ApiException $e) {
+ return $out->setStatus(new Status([
+ 'code' => $e->getCode(),
+ 'message' => $e->getMessage(),
+ ]));
+ }
+
+ $result = new CheckAndMutateRowResponse();
+ $result->setPredicateMatched($predicateMatched);
+
+ return $out->setResult($result);
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param SampleRowKeysRequest $in
+ * @return SampleRowKeysResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function SampleRowKeys(GRPC\ContextInterface $ctx, Testproxy\SampleRowKeysRequest $in): Testproxy\SampleRowKeysResult
+ {
+ return new Testproxy\SampleRowKeysResult();
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param ReadModifyWriteRowRequest $in
+ * @return RowResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function ReadModifyWriteRow(GRPC\ContextInterface $ctx, Testproxy\ReadModifyWriteRowRequest $in): Testproxy\RowResult
+ {
+ // NEXT
+ return new Testproxy\RowResult();
+ }
+
+ /**
+ * @param GRPC\ContextInterface $ctx
+ * @param ExecuteQueryRequest $in
+ * @return ExecuteQueryResult
+ *
+ * @throws GRPC\Exception\InvokeException
+ */
+ public function ExecuteQuery(GRPC\ContextInterface $ctx, Testproxy\ExecuteQueryRequest $in): Testproxy\ExecuteQueryResult
+ {
+ return new Testproxy\ExecuteQueryResult();
+ }
+
+ /**
+ * @return array{0:?BigtableClient, 1:CreateClientRequest}
+ */
+ private function getClientAndConfig(string $clientId): array
+ {
+ if (!$this->cache->has($clientId)) {
+ throw new \Exception(sprintf('Client ID "%s" not found', $clientId));
+ }
+
+ $config = $this->cache->get($clientId);
+
+ // @see self::CloseClient
+ if ($this->cache->has($clientId . '-closed')) {
+ return [null, $config];
+ }
+
+ $client = new BigtableClient([
+ 'projectId' => $config->getProjectId(),
+ 'apiEndpoint' => $config->getDataTarget(),
+ 'credentials' => new InsecureCredentialsWrapper(),
+ 'transportConfig' => [
+ 'grpc' => [
+ 'stubOpts' => [
+ 'credentials' => ChannelCredentials::createInsecure()
+ ]
+ ]
+ ],
+ ]);
+
+ return [$client, $config];
+ }
+
+ private function getTimeoutMillis(?\Google\Protobuf\Duration $timeout): ?int
+ {
+ if ($timeout === null) {
+ return null;
+ }
+ return ($timeout->getSeconds() * 1000) + ($timeout->getNanos() / 1000000);
+ }
+
+ private function protoToMutations(RepeatedField|null $protoMutations): Mutations|null
+ {
+ if (!$protoMutations) {
+ return null;
+ }
+ $mutations = new Mutations();
+ $reflection = new \ReflectionClass($mutations);
+ $property = $reflection->getProperty('mutations');
+ $property->setAccessible(true);
+ $property->setValue($mutations, $protoMutations);
+
+ return $mutations;
+ }
+}
diff --git a/Bigtable/tests/Conformance/proxy/test_proxy.proto b/Bigtable/tests/Conformance/proxy/test_proxy.proto
new file mode 100644
index 000000000000..e7caef0e7bf5
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/test_proxy.proto
@@ -0,0 +1,282 @@
+// Copyright 2023 Google LLC
+//
+// 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.
+
+syntax = "proto3";
+
+package google.bigtable.testproxy;
+
+import "google/api/client.proto";
+import "google/bigtable/v2/bigtable.proto";
+import "google/bigtable/v2/data.proto";
+import "google/protobuf/duration.proto";
+import "google/rpc/status.proto";
+
+option go_package = "./testproxypb";
+option java_multiple_files = true;
+option java_package = "com.google.cloud.bigtable.testproxy";
+
+// A config flag that dictates how the optional features should be enabled
+// during the client creation. The optional features customize how the client
+// interacts with the server, and are defined in
+// https://github.com/googleapis/googleapis/blob/master/google/bigtable/v2/feature_flags.proto
+enum OptionalFeatureConfig {
+ OPTIONAL_FEATURE_CONFIG_DEFAULT = 0;
+
+ OPTIONAL_FEATURE_CONFIG_ENABLE_ALL = 1;
+}
+
+// Request to test proxy service to create a client object.
+message CreateClientRequest {
+ // A unique ID associated with the client object to be created.
+ string client_id = 1;
+
+ // The "host:port" address of the data API endpoint (i.e. the backend being
+ // proxied to). Example: 127.0.0.1:38543. If you want to connect to a local
+ // emulator via BIGTABLE_EMULATOR_HOST environment variable, you can use
+ // "emulator" instead of "host:port" for this field.
+ string data_target = 2;
+
+ // The project for all calls on this client.
+ string project_id = 3;
+
+ // The instance for all calls on this client.
+ string instance_id = 4;
+
+ // Optional app profile for all calls on this client.
+ // Some client bindings allow specifying the app profile on a per-operation
+ // basis. We don't yet support this in the proxy API, but may in the future.
+ string app_profile_id = 5;
+
+ // If provided, a custom timeout will be set for each API call conducted by
+ // the created client. Otherwise, the default timeout from the client library
+ // will be used. Note that the override applies to all the methods.
+ google.protobuf.Duration per_operation_timeout = 6;
+
+ // Optional config that dictates how the optional features should be enabled
+ // during the client creation. Please check the enum type's docstring above.
+ OptionalFeatureConfig optional_feature_config = 7;
+}
+
+// Response from test proxy service for CreateClientRequest.
+message CreateClientResponse {}
+
+// Request to test proxy service to close a client object.
+message CloseClientRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+}
+
+// Response from test proxy service for CloseClientRequest.
+message CloseClientResponse {}
+
+// Request to test proxy service to remove a client object.
+message RemoveClientRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+}
+
+// Response from test proxy service for RemoveClientRequest.
+message RemoveClientResponse {}
+
+// Request to test proxy service to read a row.
+message ReadRowRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+
+ // The unique name of the table from which to read the row.
+ // Values are of the form
+ // `projects//instances//tables/`.
+ string table_name = 4;
+
+ // The row key of the target row.
+ string row_key = 2;
+
+ // The row filter to be applied to the target row.
+ google.bigtable.v2.RowFilter filter = 3;
+}
+
+// Response from test proxy service for ReadRowRequest or
+// ReadModifyWriteRowRequest.
+message RowResult {
+ // The RPC status from the client binding.
+ google.rpc.Status status = 1;
+
+ // The contents of a single row.
+ google.bigtable.v2.Row row = 2;
+}
+
+// Request to test proxy service to read rows.
+message ReadRowsRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+
+ // The raw request to the Bigtable server.
+ google.bigtable.v2.ReadRowsRequest request = 2;
+
+ // The streaming read can be canceled before all items are seen.
+ // Has no effect if non-positive.
+ int32 cancel_after_rows = 3;
+}
+
+// Response from test proxy service for ReadRowsRequest.
+message RowsResult {
+ // The RPC status from the client binding.
+ google.rpc.Status status = 1;
+
+ // The contents of rows.
+ repeated google.bigtable.v2.Row rows = 2;
+}
+
+// Request to test proxy service to mutate a row.
+message MutateRowRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+
+ // The raw request to the Bigtable server.
+ google.bigtable.v2.MutateRowRequest request = 2;
+}
+
+// Response from test proxy service for MutateRowRequest.
+message MutateRowResult {
+ // The RPC status from the client binding.
+ google.rpc.Status status = 1;
+}
+
+// Request to test proxy service to mutate rows.
+message MutateRowsRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+
+ // The raw request to the Bigtable server.
+ google.bigtable.v2.MutateRowsRequest request = 2;
+}
+
+// Response from test proxy service for MutateRowsRequest.
+message MutateRowsResult {
+ // The RPC status from the client binding, corresponding to the
+ // whole operation.
+ google.rpc.Status status = 1;
+
+ // The results corresponding to the failed rows.
+ repeated google.bigtable.v2.MutateRowsResponse.Entry entries = 2;
+}
+
+// Request to test proxy service to check and mutate a row.
+message CheckAndMutateRowRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+
+ // The raw request to the Bigtable server.
+ google.bigtable.v2.CheckAndMutateRowRequest request = 2;
+}
+
+// Response from test proxy service for CheckAndMutateRowRequest.
+message CheckAndMutateRowResult {
+ // The RPC status from the client binding.
+ google.rpc.Status status = 1;
+
+ // The raw response from the Bigtable server.
+ google.bigtable.v2.CheckAndMutateRowResponse result = 2;
+}
+
+// Request to test proxy service to sample row keys.
+message SampleRowKeysRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+
+ // The raw request to the Bigtable server.
+ google.bigtable.v2.SampleRowKeysRequest request = 2;
+}
+
+// Response from test proxy service for SampleRowKeysRequest.
+message SampleRowKeysResult {
+ // The RPC status from the client binding.
+ google.rpc.Status status = 1;
+
+ // The raw responses from the Bigtable server.
+ repeated google.bigtable.v2.SampleRowKeysResponse samples = 2;
+}
+
+// Request to test proxy service to read modify write a row.
+message ReadModifyWriteRowRequest {
+ // The ID of the target client object.
+ string client_id = 1;
+
+ // The raw request to the Bigtable server.
+ google.bigtable.v2.ReadModifyWriteRowRequest request = 2;
+}
+
+// Note that all RPCs are unary, even when the equivalent client binding call
+// may be streaming. This is an intentional simplification.
+//
+// Most methods have sync (default) and async variants. For async variants,
+// the proxy is expected to perform the async operation, then wait for results
+// before delivering them back to the driver client.
+//
+// Operations that may have interesting concurrency characteristics are
+// represented explicitly in the API (see ReadRowsRequest.cancel_after_rows).
+// We include such operations only when they can be meaningfully performed
+// through client bindings.
+//
+// Users should generally avoid setting deadlines for requests to the Proxy
+// because operations are not cancelable. If the deadline is set anyway, please
+// understand that the underlying operation will continue to be executed even
+// after the deadline expires.
+service CloudBigtableV2TestProxy {
+ option (google.api.default_host) =
+ "bigtable-test-proxy-not-accessible.googleapis.com";
+
+ // Client management:
+ //
+ // Creates a client in the proxy.
+ // Each client has its own dedicated channel(s), and can be used concurrently
+ // and independently with other clients.
+ rpc CreateClient(CreateClientRequest) returns (CreateClientResponse) {}
+
+ // Closes a client in the proxy, making it not accept new requests.
+ rpc CloseClient(CloseClientRequest) returns (CloseClientResponse) {}
+
+ // Removes a client in the proxy, making it inaccessible. Client closing
+ // should be done by CloseClient() separately.
+ rpc RemoveClient(RemoveClientRequest) returns (RemoveClientResponse) {}
+
+ // Bigtable operations: for each operation, you should use the synchronous or
+ // asynchronous variant of the client method based on the `use_async_method`
+ // setting of the client instance. For starters, you can choose to implement
+ // one variant, and return UNIMPLEMENTED status for the other.
+ //
+ // Reads a row with the client instance.
+ // The result row may not be present in the response.
+ // Callers should check for it (e.g. calling has_row() in C++).
+ rpc ReadRow(ReadRowRequest) returns (RowResult) {}
+
+ // Reads rows with the client instance.
+ rpc ReadRows(ReadRowsRequest) returns (RowsResult) {}
+
+ // Writes a row with the client instance.
+ rpc MutateRow(MutateRowRequest) returns (MutateRowResult) {}
+
+ // Writes multiple rows with the client instance.
+ rpc BulkMutateRows(MutateRowsRequest) returns (MutateRowsResult) {}
+
+ // Performs a check-and-mutate-row operation with the client instance.
+ rpc CheckAndMutateRow(CheckAndMutateRowRequest)
+ returns (CheckAndMutateRowResult) {}
+
+ // Obtains a row key sampling with the client instance.
+ rpc SampleRowKeys(SampleRowKeysRequest) returns (SampleRowKeysResult) {}
+
+ // Performs a read-modify-write operation with the client.
+ rpc ReadModifyWriteRow(ReadModifyWriteRowRequest) returns (RowResult) {}
+}
diff --git a/Bigtable/tests/Conformance/proxy/worker.php b/Bigtable/tests/Conformance/proxy/worker.php
new file mode 100644
index 000000000000..4eada76b8a3f
--- /dev/null
+++ b/Bigtable/tests/Conformance/proxy/worker.php
@@ -0,0 +1,20 @@
+ true, // optional (default: false)
+]);
+
+$server->registerService(CloudBigtableV2TestProxyInterface::class, new ProxyService());
+
+$server->serve(Worker::create());
diff --git a/phpcs-ruleset.xml b/phpcs-ruleset.xml
index dbfc4bf3d0d3..f3ce39e0d0c1 100644
--- a/phpcs-ruleset.xml
+++ b/phpcs-ruleset.xml
@@ -22,6 +22,7 @@
AccessContextManager/src/Type
Asset/external
BigQueryDataExchange/src/Common
+ Bigtable/tests/Conformance/proxy/src
Core/src/Testing
GSuiteAddOns/external
OsLogin/src/Common