Repository: googleapis/java-storage
Pull request #1119 (2021-10-20 00:32:58)

test(retry): add a test which ensures expected behavior of new retry handlers
In addition to providing the new handlers which are validated to some extent with the retry conformance suite, we also want to ensure we maintain support for "java specific" errors which historically are already handled my the core library. In some ways this also functions as a regression suite of errors we want to keep track of for retry purposes.


Patch:
diff --git a/.github/release-please.yml b/.github/release-please.yml
index ff422365..069b9732 100644
--- a/.github/release-please.yml
+++ b/.github/release-please.yml
@@ -18,3 +18,7 @@ branches:
     handleGHRelease: true
     releaseType: java-yoshi
     branch: java7
+  - bumpMinorPreMajor: true
+    handleGHRelease: true
+    releaseType: java-yoshi
+    branch: 2.1.x
diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml
index 85d52c14..600b1584 100644
--- a/.github/sync-repo-settings.yaml
+++ b/.github/sync-repo-settings.yaml
@@ -76,6 +76,20 @@ branchProtectionRules:
       - units (11)
       - 'Kokoro - Test: Integration'
       - cla/google
+  - pattern: 2.1.x
+    isAdminEnforced: true
+    requiredApprovingReviewCount: 1
+    requiresCodeOwnerReviews: true
+    requiresStrictStatusChecks: false
+    requiredStatusCheckContexts:
+      - dependencies (8)
+      - dependencies (11)
+      - lint
+      - clirr
+      - units (8)
+      - units (11)
+      - 'Kokoro - Test: Integration'
+      - cla/google
 permissionRules:
   - team: yoshi-admins
     permission: admin
diff --git a/.kokoro/build.sh b/.kokoro/build.sh
index 1d79a81d..dc691c03 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -69,6 +69,11 @@ integration)
       verify
     RETURN_CODE=$?
     ;;
+graalvm)
+    # Run Unit and Integration Tests with Native Image
+    mvn test -Pnative -Penable-integration-tests
+    RETURN_CODE=$?
+    ;;
 samples)
     SAMPLES_DIR=samples
     # only run ITs in snapshot/ on presubmit PRs. run ITs in all 3 samples/ subdirectories otherwise.
diff --git a/.kokoro/dependencies.sh b/.kokoro/dependencies.sh
index 9a5105d7..d7476cfe 100755
--- a/.kokoro/dependencies.sh
+++ b/.kokoro/dependencies.sh
@@ -38,15 +38,13 @@ function determineMavenOpts() {
       | sed -E 's/^(1\.[0-9]\.0).*$/\1/g'
   )
 
-  case $javaVersion in
-    "17")
+  if [[ $javaVersion == 17* ]]
+    then
       # MaxPermSize is no longer supported as of jdk 17
       echo -n "-Xmx1024m"
-      ;;
-    *)
+  else
       echo -n "-Xmx1024m -XX:MaxPermSize=128m"
-      ;;
-  esac
+  fi
 }
 
 export MAVEN_OPTS=$(determineMavenOpts)
diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg
new file mode 100644
index 00000000..4c7225ec
--- /dev/null
+++ b/.kokoro/presubmit/graalvm-native.cfg
@@ -0,0 +1,33 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+# Configure the docker image for kokoro-trampoline.
+env_vars: {
+  key: "TRAMPOLINE_IMAGE"
+  value: "gcr.io/cloud-devrel-kokoro-resources/graalvm"
+}
+
+env_vars: {
+  key: "JOB_TYPE"
+  value: "graalvm"
+}
+
+# TODO: remove this after we've migrated all tests and scripts
+env_vars: {
+  key: "GCLOUD_PROJECT"
+  value: "gcloud-devel"
+}
+
+env_vars: {
+  key: "GOOGLE_CLOUD_PROJECT"
+  value: "gcloud-devel"
+}
+
+env_vars: {
+  key: "GOOGLE_APPLICATION_CREDENTIALS"
+  value: "secret_manager/java-it-service-account"
+}
+
+env_vars: {
+  key: "SECRET_MANAGER_KEYS"
+  value: "java-it-service-account"
+}
diff --git a/google-cloud-storage/pom.xml b/google-cloud-storage/pom.xml
index 4429eca2..3eb2ef73 100644
--- a/google-cloud-storage/pom.xml
+++ b/google-cloud-storage/pom.xml
@@ -16,7 +16,7 @@
   </parent>
   <properties>
     <site.installationModule>google-cloud-storage</site.installationModule>
-    <kms.version>0.93.1</kms.version>
+    <kms.version>0.93.2</kms.version>
   </properties>
   <dependencies>
     <dependency>
diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultStorageRetryStrategy.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultStorageRetryStrategy.java
index 66344867..5eb83c90 100644
--- a/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultStorageRetryStrategy.java
+++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultStorageRetryStrategy.java
@@ -73,41 +73,48 @@ final class DefaultStorageRetryStrategy implements StorageRetryStrategy {
 
     @Override
     public RetryResult beforeEval(Exception exception) {
-      Throwable t = exception;
-
-      if (t instanceof BaseServiceException) {
-        BaseServiceException storageException = (BaseServiceException) t;
-        Throwable cause = storageException.getCause();
-        // if the cause of the exception is an IOException lift it before we continue
-        // evaluation
-        if (cause instanceof IOException) {
-          t = cause;
-        }
-      }
-
-      if (t instanceof BaseServiceException) {
-        BaseServiceException baseServiceException = (BaseServiceException) t;
-        int code = baseServiceException.getCode();
-        String reason = baseServiceException.getReason();
-        return shouldRetryCode(code, reason);
-      } else if (t instanceof HttpResponseException) {
-        int code = ((HttpResponseException) t).getStatusCode();
-        return shouldRetryCode(code, null);
-      } else if (t instanceof IOException) {
-        IOException ioException = (IOException) t;
-        return BaseServiceException.isRetryable(idempotent, ioException)
-            ? RetryResult.RETRY
-            : RetryResult.NO_RETRY;
+      if (exception instanceof BaseServiceException) {
+        BaseServiceException baseServiceException = (BaseServiceException) exception;
+        return deepShouldRetry(baseServiceException);
+      } else if (exception instanceof HttpResponseException) {
+        int code = ((HttpResponseException) exception).getStatusCode();
+        return shouldRetryCodeReason(code, null);
+      } else if (exception instanceof IOException) {
+        IOException ioException = (IOException) exception;
+        return shouldRetryIOException(ioException);
       }
       return RetryResult.CONTINUE_EVALUATION;
     }
 
-    private RetryResult shouldRetryCode(Integer code, String reason) {
+    private RetryResult shouldRetryCodeReason(Integer code, String reason) {
       if (BaseServiceException.isRetryable(code, reason, idempotent, retryableErrors)) {
         return RetryResult.RETRY;
       } else {
         return RetryResult.NO_RETRY;
       }
     }
+
+    private RetryResult shouldRetryIOException(IOException ioException) {
+      if (BaseServiceException.isRetryable(idempotent, ioException)) {
+        return RetryResult.RETRY;
+      } else {
+        return RetryResult.NO_RETRY;
+      }
+    }
+
+    private RetryResult deepShouldRetry(BaseServiceException baseServiceException) {
+      if (baseServiceException.getCode() == BaseServiceException.UNKNOWN_CODE
+          && baseServiceException.getReason() == null) {
+        final Throwable cause = baseServiceException.getCause();
+        if (cause instanceof IOException) {
+          IOException ioException = (IOException) cause;
+          return shouldRetryIOException(ioException);
+        }
+      }
+
+      int code = baseServiceException.getCode();
+      String reason = baseServiceException.getReason();
+      return shouldRetryCodeReason(code, reason);
+    }
   }
 }
diff --git a/pom.xml b/pom.xml
index 2d53736f..0940c1a6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,7 @@
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-shared-config</artifactId>
-    <version>1.1.0</version>
+    <version>1.2.0</version>
   </parent>
 
   <developers>
@@ -70,7 +70,7 @@
       <dependency>
         <groupId>com.google.apis</groupId>
         <artifactId>google-api-services-storage</artifactId>
-        <version>v1-rev20210918-1.32.1</version>
+        <version>v1-rev20211018-1.32.1</version>
       </dependency>
       <dependency>
         <groupId>org.easymock</groupId>
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java
index 39842b0a..91808f23 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java
@@ -2806,7 +2806,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
 
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-      if (!getDefaultKmsKeyBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(defaultKmsKey_)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, defaultKmsKey_);
       }
       unknownFields.writeTo(output);
@@ -2818,7 +2818,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
       if (size != -1) return size;
 
       size = 0;
-      if (!getDefaultKmsKeyBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(defaultKmsKey_)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, defaultKmsKey_);
       }
       size += unknownFields.getSerializedSize();
@@ -6010,10 +6010,10 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
         @java.lang.Override
         public void writeTo(com.google.protobuf.CodedOutputStream output)
             throws java.io.IOException {
-          if (!getTypeBytes().isEmpty()) {
+          if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(type_)) {
             com.google.protobuf.GeneratedMessageV3.writeString(output, 1, type_);
           }
-          if (!getStorageClassBytes().isEmpty()) {
+          if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(storageClass_)) {
             com.google.protobuf.GeneratedMessageV3.writeString(output, 2, storageClass_);
           }
           unknownFields.writeTo(output);
@@ -6025,10 +6025,10 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
           if (size != -1) return size;
 
           size = 0;
-          if (!getTypeBytes().isEmpty()) {
+          if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(type_)) {
             size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, type_);
           }
-          if (!getStorageClassBytes().isEmpty()) {
+          if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(storageClass_)) {
             size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, storageClass_);
           }
           size += unknownFields.getSerializedSize();
@@ -6625,7 +6625,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * condition.
          * </pre>
          *
-         * <code>int32 age_days = 1;</code>
+         * <code>optional int32 age_days = 1;</code>
          *
          * @return Whether the ageDays field is set.
          */
@@ -6640,7 +6640,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * condition.
          * </pre>
          *
-         * <code>int32 age_days = 1;</code>
+         * <code>optional int32 age_days = 1;</code>
          *
          * @return The ageDays.
          */
@@ -6693,7 +6693,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * is `false`, it matches archived objects.
          * </pre>
          *
-         * <code>bool is_live = 3;</code>
+         * <code>optional bool is_live = 3;</code>
          *
          * @return Whether the isLive field is set.
          */
@@ -6707,7 +6707,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * is `false`, it matches archived objects.
          * </pre>
          *
-         * <code>bool is_live = 3;</code>
+         * <code>optional bool is_live = 3;</code>
          *
          * @return The isLive.
          */
@@ -6722,7 +6722,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * the live version) newer than this version of the object.
          * </pre>
          *
-         * <code>int32 num_newer_versions = 4;</code>
+         * <code>optional int32 num_newer_versions = 4;</code>
          *
          * @return Whether the numNewerVersions field is set.
          */
@@ -6736,7 +6736,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * the live version) newer than this version of the object.
          * </pre>
          *
-         * <code>int32 num_newer_versions = 4;</code>
+         * <code>optional int32 num_newer_versions = 4;</code>
          *
          * @return The numNewerVersions.
          */
@@ -6814,7 +6814,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * The value of the field must be a nonnegative integer.
          * </pre>
          *
-         * <code>int32 days_since_custom_time = 7;</code>
+         * <code>optional int32 days_since_custom_time = 7;</code>
          *
          * @return Whether the daysSinceCustomTime field is set.
          */
@@ -6828,7 +6828,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * The value of the field must be a nonnegative integer.
          * </pre>
          *
-         * <code>int32 days_since_custom_time = 7;</code>
+         * <code>optional int32 days_since_custom_time = 7;</code>
          *
          * @return The daysSinceCustomTime.
          */
@@ -6883,7 +6883,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * eligible for Lifecycle action as soon as it becomes noncurrent.
          * </pre>
          *
-         * <code>int32 days_since_noncurrent_time = 9;</code>
+         * <code>optional int32 days_since_noncurrent_time = 9;</code>
          *
          * @return Whether the daysSinceNoncurrentTime field is set.
          */
@@ -6899,7 +6899,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * eligible for Lifecycle action as soon as it becomes noncurrent.
          * </pre>
          *
-         * <code>int32 days_since_noncurrent_time = 9;</code>
+         * <code>optional int32 days_since_noncurrent_time = 9;</code>
          *
          * @return The daysSinceNoncurrentTime.
          */
@@ -7135,7 +7135,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * condition.
          * </pre>
          *
-         * <code>int32 age_days = 1;</code>
+         * <code>optional int32 age_days = 1;</code>
          *
          * @return Whether the ageDays field is set.
          */
@@ -7153,7 +7153,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * condition.
          * </pre>
          *
-         * <code>int32 age_days = 1;</code>
+         * <code>optional int32 age_days = 1;</code>
          *
          * @return The ageDays.
          */
@@ -7224,7 +7224,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * is `false`, it matches archived objects.
          * </pre>
          *
-         * <code>bool is_live = 3;</code>
+         * <code>optional bool is_live = 3;</code>
          *
          * @return Whether the isLive field is set.
          */
@@ -7241,7 +7241,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * is `false`, it matches archived objects.
          * </pre>
          *
-         * <code>bool is_live = 3;</code>
+         * <code>optional bool is_live = 3;</code>
          *
          * @return The isLive.
          */
@@ -7261,7 +7261,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * the live version) newer than this version of the object.
          * </pre>
          *
-         * <code>int32 num_newer_versions = 4;</code>
+         * <code>optional int32 num_newer_versions = 4;</code>
          *
          * @return Whether the numNewerVersions field is set.
          */
@@ -7278,7 +7278,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * the live version) newer than this version of the object.
          * </pre>
          *
-         * <code>int32 num_newer_versions = 4;</code>
+         * <code>optional int32 num_newer_versions = 4;</code>
          *
          * @return The numNewerVersions.
          */
@@ -7371,7 +7371,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * The value of the field must be a nonnegative integer.
          * </pre>
          *
-         * <code>int32 days_since_custom_time = 7;</code>
+         * <code>optional int32 days_since_custom_time = 7;</code>
          *
          * @return Whether the daysSinceCustomTime field is set.
          */
@@ -7388,7 +7388,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * The value of the field must be a nonnegative integer.
          * </pre>
          *
-         * <code>int32 days_since_custom_time = 7;</code>
+         * <code>optional int32 days_since_custom_time = 7;</code>
          *
          * @return The daysSinceCustomTime.
          */
@@ -7461,7 +7461,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * eligible for Lifecycle action as soon as it becomes noncurrent.
          * </pre>
          *
-         * <code>int32 days_since_noncurrent_time = 9;</code>
+         * <code>optional int32 days_since_noncurrent_time = 9;</code>
          *
          * @return Whether the daysSinceNoncurrentTime field is set.
          */
@@ -7480,7 +7480,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
          * eligible for Lifecycle action as soon as it becomes noncurrent.
          * </pre>
          *
-         * <code>int32 days_since_noncurrent_time = 9;</code>
+         * <code>optional int32 days_since_noncurrent_time = 9;</code>
          *
          * @return The daysSinceNoncurrentTime.
          */
@@ -8106,7 +8106,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * condition.
            * </pre>
            *
-           * <code>int32 age_days = 1;</code>
+           * <code>optional int32 age_days = 1;</code>
            *
            * @return Whether the ageDays field is set.
            */
@@ -8124,7 +8124,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * condition.
            * </pre>
            *
-           * <code>int32 age_days = 1;</code>
+           * <code>optional int32 age_days = 1;</code>
            *
            * @return The ageDays.
            */
@@ -8142,7 +8142,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * condition.
            * </pre>
            *
-           * <code>int32 age_days = 1;</code>
+           * <code>optional int32 age_days = 1;</code>
            *
            * @param value The ageDays to set.
            * @return This builder for chaining.
@@ -8163,7 +8163,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * condition.
            * </pre>
            *
-           * <code>int32 age_days = 1;</code>
+           * <code>optional int32 age_days = 1;</code>
            *
            * @return This builder for chaining.
            */
@@ -8372,7 +8372,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * is `false`, it matches archived objects.
            * </pre>
            *
-           * <code>bool is_live = 3;</code>
+           * <code>optional bool is_live = 3;</code>
            *
            * @return Whether the isLive field is set.
            */
@@ -8389,7 +8389,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * is `false`, it matches archived objects.
            * </pre>
            *
-           * <code>bool is_live = 3;</code>
+           * <code>optional bool is_live = 3;</code>
            *
            * @return The isLive.
            */
@@ -8406,7 +8406,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * is `false`, it matches archived objects.
            * </pre>
            *
-           * <code>bool is_live = 3;</code>
+           * <code>optional bool is_live = 3;</code>
            *
            * @param value The isLive to set.
            * @return This builder for chaining.
@@ -8426,7 +8426,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * is `false`, it matches archived objects.
            * </pre>
            *
-           * <code>bool is_live = 3;</code>
+           * <code>optional bool is_live = 3;</code>
            *
            * @return This builder for chaining.
            */
@@ -8447,7 +8447,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * the live version) newer than this version of the object.
            * </pre>
            *
-           * <code>int32 num_newer_versions = 4;</code>
+           * <code>optional int32 num_newer_versions = 4;</code>
            *
            * @return Whether the numNewerVersions field is set.
            */
@@ -8464,7 +8464,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * the live version) newer than this version of the object.
            * </pre>
            *
-           * <code>int32 num_newer_versions = 4;</code>
+           * <code>optional int32 num_newer_versions = 4;</code>
            *
            * @return The numNewerVersions.
            */
@@ -8481,7 +8481,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * the live version) newer than this version of the object.
            * </pre>
            *
-           * <code>int32 num_newer_versions = 4;</code>
+           * <code>optional int32 num_newer_versions = 4;</code>
            *
            * @param value The numNewerVersions to set.
            * @return This builder for chaining.
@@ -8501,7 +8501,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * the live version) newer than this version of the object.
            * </pre>
            *
-           * <code>int32 num_newer_versions = 4;</code>
+           * <code>optional int32 num_newer_versions = 4;</code>
            *
            * @return This builder for chaining.
            */
@@ -8718,7 +8718,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * The value of the field must be a nonnegative integer.
            * </pre>
            *
-           * <code>int32 days_since_custom_time = 7;</code>
+           * <code>optional int32 days_since_custom_time = 7;</code>
            *
            * @return Whether the daysSinceCustomTime field is set.
            */
@@ -8735,7 +8735,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * The value of the field must be a nonnegative integer.
            * </pre>
            *
-           * <code>int32 days_since_custom_time = 7;</code>
+           * <code>optional int32 days_since_custom_time = 7;</code>
            *
            * @return The daysSinceCustomTime.
            */
@@ -8752,7 +8752,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * The value of the field must be a nonnegative integer.
            * </pre>
            *
-           * <code>int32 days_since_custom_time = 7;</code>
+           * <code>optional int32 days_since_custom_time = 7;</code>
            *
            * @param value The daysSinceCustomTime to set.
            * @return This builder for chaining.
@@ -8772,7 +8772,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * The value of the field must be a nonnegative integer.
            * </pre>
            *
-           * <code>int32 days_since_custom_time = 7;</code>
+           * <code>optional int32 days_since_custom_time = 7;</code>
            *
            * @return This builder for chaining.
            */
@@ -8985,7 +8985,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * eligible for Lifecycle action as soon as it becomes noncurrent.
            * </pre>
            *
-           * <code>int32 days_since_noncurrent_time = 9;</code>
+           * <code>optional int32 days_since_noncurrent_time = 9;</code>
            *
            * @return Whether the daysSinceNoncurrentTime field is set.
            */
@@ -9004,7 +9004,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * eligible for Lifecycle action as soon as it becomes noncurrent.
            * </pre>
            *
-           * <code>int32 days_since_noncurrent_time = 9;</code>
+           * <code>optional int32 days_since_noncurrent_time = 9;</code>
            *
            * @return The daysSinceNoncurrentTime.
            */
@@ -9023,7 +9023,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * eligible for Lifecycle action as soon as it becomes noncurrent.
            * </pre>
            *
-           * <code>int32 days_since_noncurrent_time = 9;</code>
+           * <code>optional int32 days_since_noncurrent_time = 9;</code>
            *
            * @param value The daysSinceNoncurrentTime to set.
            * @return This builder for chaining.
@@ -9045,7 +9045,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
            * eligible for Lifecycle action as soon as it becomes noncurrent.
            * </pre>
            *
-           * <code>int32 days_since_noncurrent_time = 9;</code>
+           * <code>optional int32 days_since_noncurrent_time = 9;</code>
            *
            * @return This builder for chaining.
            */
@@ -11314,10 +11314,10 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
 
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-      if (!getLogBucketBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(logBucket_)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, logBucket_);
       }
-      if (!getLogObjectPrefixBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(logObjectPrefix_)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, logObjectPrefix_);
       }
       unknownFields.writeTo(output);
@@ -11329,10 +11329,10 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
       if (size != -1) return size;
 
       size = 0;
-      if (!getLogBucketBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(logBucket_)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, logBucket_);
       }
-      if (!getLogObjectPrefixBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(logObjectPrefix_)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, logObjectPrefix_);
       }
       size += unknownFields.getSerializedSize();
@@ -13755,10 +13755,10 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
 
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-      if (!getMainPageSuffixBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(mainPageSuffix_)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, mainPageSuffix_);
       }
-      if (!getNotFoundPageBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(notFoundPage_)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 2, notFoundPage_);
       }
       unknownFields.writeTo(output);
@@ -13770,10 +13770,10 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
       if (size != -1) return size;
 
       size = 0;
-      if (!getMainPageSuffixBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(mainPageSuffix_)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, mainPageSuffix_);
       }
-      if (!getNotFoundPageBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(notFoundPage_)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, notFoundPage_);
       }
       size += unknownFields.getSerializedSize();
@@ -15792,25 +15792,25 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getNameBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
     }
-    if (!getBucketIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(bucketId_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 2, bucketId_);
     }
-    if (!getProjectBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(project_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 3, project_);
     }
     if (metageneration_ != 0L) {
       output.writeInt64(4, metageneration_);
     }
-    if (!getLocationBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(location_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 5, location_);
     }
-    if (!getLocationTypeBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(locationType_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 6, locationType_);
     }
-    if (!getStorageClassBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(storageClass_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 7, storageClass_);
     }
     for (int i = 0; i < acl_.size(); i++) {
@@ -15875,25 +15875,25 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3
     if (size != -1) return size;
 
     size = 0;
-    if (!getNameBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
     }
-    if (!getBucketIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(bucketId_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, bucketId_);
     }
-    if (!getProjectBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(project_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, project_);
     }
     if (metageneration_ != 0L) {
       size += com.google.protobuf.CodedOutputStream.computeInt64Size(4, metageneration_);
     }
-    if (!getLocationBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(location_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, location_);
     }
-    if (!getLocationTypeBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(locationType_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, locationType_);
     }
-    if (!getStorageClassBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(storageClass_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, storageClass_);
     }
     for (int i = 0; i < acl_.size(); i++) {
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java
index 116695c1..3c6c4a54 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java
@@ -550,22 +550,22 @@ public final class BucketAccessControl extends com.google.protobuf.GeneratedMess
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getRoleBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(role_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, role_);
     }
-    if (!getIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 2, id_);
     }
-    if (!getEntityBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entity_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 3, entity_);
     }
-    if (!getEntityIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entityId_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 4, entityId_);
     }
-    if (!getEmailBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(email_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 5, email_);
     }
-    if (!getDomainBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(domain_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 6, domain_);
     }
     if (projectTeam_ != null) {
@@ -580,22 +580,22 @@ public final class BucketAccessControl extends com.google.protobuf.GeneratedMess
     if (size != -1) return size;
 
     size = 0;
-    if (!getRoleBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(role_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, role_);
     }
-    if (!getIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, id_);
     }
-    if (!getEntityBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entity_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, entity_);
     }
-    if (!getEntityIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entityId_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, entityId_);
     }
-    if (!getEmailBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(email_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, email_);
     }
-    if (!getDomainBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(domain_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, domain_);
     }
     if (projectTeam_ != null) {
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java
index e28d8e7a..f84e379e 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java
@@ -145,7 +145,7 @@ public final class ChecksummedData extends com.google.protobuf.GeneratedMessageV
    * If set, the CRC32C digest of the content field.
    * </pre>
    *
-   * <code>fixed32 crc32c = 2;</code>
+   * <code>optional fixed32 crc32c = 2;</code>
    *
    * @return Whether the crc32c field is set.
    */
@@ -160,7 +160,7 @@ public final class ChecksummedData extends com.google.protobuf.GeneratedMessageV
    * If set, the CRC32C digest of the content field.
    * </pre>
    *
-   * <code>fixed32 crc32c = 2;</code>
+   * <code>optional fixed32 crc32c = 2;</code>
    *
    * @return The crc32c.
    */
@@ -574,7 +574,7 @@ public final class ChecksummedData extends com.google.protobuf.GeneratedMessageV
      * If set, the CRC32C digest of the content field.
      * </pre>
      *
-     * <code>fixed32 crc32c = 2;</code>
+     * <code>optional fixed32 crc32c = 2;</code>
      *
      * @return Whether the crc32c field is set.
      */
@@ -589,7 +589,7 @@ public final class ChecksummedData extends com.google.protobuf.GeneratedMessageV
      * If set, the CRC32C digest of the content field.
      * </pre>
      *
-     * <code>fixed32 crc32c = 2;</code>
+     * <code>optional fixed32 crc32c = 2;</code>
      *
      * @return The crc32c.
      */
@@ -604,7 +604,7 @@ public final class ChecksummedData extends com.google.protobuf.GeneratedMessageV
      * If set, the CRC32C digest of the content field.
      * </pre>
      *
-     * <code>fixed32 crc32c = 2;</code>
+     * <code>optional fixed32 crc32c = 2;</code>
      *
      * @param value The crc32c to set.
      * @return This builder for chaining.
@@ -622,7 +622,7 @@ public final class ChecksummedData extends com.google.protobuf.GeneratedMessageV
      * If set, the CRC32C digest of the content field.
      * </pre>
      *
-     * <code>fixed32 crc32c = 2;</code>
+     * <code>optional fixed32 crc32c = 2;</code>
      *
      * @return This builder for chaining.
      */
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java
index 15bded53..9fe732c8 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java
@@ -43,7 +43,7 @@ public interface ChecksummedDataOrBuilder
    * If set, the CRC32C digest of the content field.
    * </pre>
    *
-   * <code>fixed32 crc32c = 2;</code>
+   * <code>optional fixed32 crc32c = 2;</code>
    *
    * @return Whether the crc32c field is set.
    */
@@ -55,7 +55,7 @@ public interface ChecksummedDataOrBuilder
    * If set, the CRC32C digest of the content field.
    * </pre>
    *
-   * <code>fixed32 crc32c = 2;</code>
+   * <code>optional fixed32 crc32c = 2;</code>
    *
    * @return The crc32c.
    */
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java
index 6d397814..3dfad0b8 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java
@@ -224,7 +224,7 @@ public final class CommonObjectRequestParams extends com.google.protobuf.Generat
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getEncryptionAlgorithmBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(encryptionAlgorithm_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, encryptionAlgorithm_);
     }
     if (!encryptionKeyBytes_.isEmpty()) {
@@ -242,7 +242,7 @@ public final class CommonObjectRequestParams extends com.google.protobuf.Generat
     if (size != -1) return size;
 
     size = 0;
-    if (!getEncryptionAlgorithmBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(encryptionAlgorithm_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, encryptionAlgorithm_);
     }
     if (!encryptionKeyBytes_.isEmpty()) {
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonRequestParams.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonRequestParams.java
index 7fb71c02..70e27fdc 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonRequestParams.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonRequestParams.java
@@ -180,7 +180,7 @@ public final class CommonRequestParams extends com.google.protobuf.GeneratedMess
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getUserProjectBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(userProject_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, userProject_);
     }
     unknownFields.writeTo(output);
@@ -192,7 +192,7 @@ public final class CommonRequestParams extends com.google.protobuf.GeneratedMess
     if (size != -1) return size;
 
     size = 0;
-    if (!getUserProjectBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(userProject_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, userProject_);
     }
     size += unknownFields.getSerializedSize();
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java
index b6377857..9914081c 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java
@@ -607,7 +607,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
 
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-      if (!getEncryptionAlgorithmBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(encryptionAlgorithm_)) {
         com.google.protobuf.GeneratedMessageV3.writeString(output, 1, encryptionAlgorithm_);
       }
       if (!keySha256Bytes_.isEmpty()) {
@@ -622,7 +622,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
       if (size != -1) return size;
 
       size = 0;
-      if (!getEncryptionAlgorithmBytes().isEmpty()) {
+      if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(encryptionAlgorithm_)) {
         size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, encryptionAlgorithm_);
       }
       if (!keySha256Bytes_.isEmpty()) {
@@ -2283,7 +2283,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
    * In a response, this field will always be set to true or false.
    * </pre>
    *
-   * <code>bool event_based_hold = 23;</code>
+   * <code>optional bool event_based_hold = 23;</code>
    *
    * @return Whether the eventBasedHold field is set.
    */
@@ -2307,7 +2307,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
    * In a response, this field will always be set to true or false.
    * </pre>
    *
-   * <code>bool event_based_hold = 23;</code>
+   * <code>optional bool event_based_hold = 23;</code>
    *
    * @return The eventBasedHold.
    */
@@ -2479,10 +2479,10 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getNameBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
     }
-    if (!getBucketBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(bucket_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 2, bucket_);
     }
     if (generation_ != 0L) {
@@ -2491,31 +2491,31 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
     if (metageneration_ != 0L) {
       output.writeInt64(4, metageneration_);
     }
-    if (!getStorageClassBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(storageClass_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 5, storageClass_);
     }
     if (size_ != 0L) {
       output.writeInt64(6, size_);
     }
-    if (!getContentEncodingBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentEncoding_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 7, contentEncoding_);
     }
-    if (!getContentDispositionBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentDisposition_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 8, contentDisposition_);
     }
-    if (!getCacheControlBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(cacheControl_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 9, cacheControl_);
     }
     for (int i = 0; i < acl_.size(); i++) {
       output.writeMessage(10, acl_.get(i));
     }
-    if (!getContentLanguageBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentLanguage_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 11, contentLanguage_);
     }
     if (deleteTime_ != null) {
       output.writeMessage(12, getDeleteTime());
     }
-    if (!getContentTypeBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentType_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 13, contentType_);
     }
     if (createTime_ != null) {
@@ -2530,7 +2530,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
     if (updateTime_ != null) {
       output.writeMessage(17, getUpdateTime());
     }
-    if (!getKmsKeyBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(kmsKey_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 18, kmsKey_);
     }
     if (updateStorageClassTime_ != null) {
@@ -2565,10 +2565,10 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
     if (size != -1) return size;
 
     size = 0;
-    if (!getNameBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
     }
-    if (!getBucketBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(bucket_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, bucket_);
     }
     if (generation_ != 0L) {
@@ -2577,31 +2577,31 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
     if (metageneration_ != 0L) {
       size += com.google.protobuf.CodedOutputStream.computeInt64Size(4, metageneration_);
     }
-    if (!getStorageClassBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(storageClass_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, storageClass_);
     }
     if (size_ != 0L) {
       size += com.google.protobuf.CodedOutputStream.computeInt64Size(6, size_);
     }
-    if (!getContentEncodingBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentEncoding_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, contentEncoding_);
     }
-    if (!getContentDispositionBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentDisposition_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, contentDisposition_);
     }
-    if (!getCacheControlBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(cacheControl_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(9, cacheControl_);
     }
     for (int i = 0; i < acl_.size(); i++) {
       size += com.google.protobuf.CodedOutputStream.computeMessageSize(10, acl_.get(i));
     }
-    if (!getContentLanguageBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentLanguage_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(11, contentLanguage_);
     }
     if (deleteTime_ != null) {
       size += com.google.protobuf.CodedOutputStream.computeMessageSize(12, getDeleteTime());
     }
-    if (!getContentTypeBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(contentType_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(13, contentType_);
     }
     if (createTime_ != null) {
@@ -2616,7 +2616,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
     if (updateTime_ != null) {
       size += com.google.protobuf.CodedOutputStream.computeMessageSize(17, getUpdateTime());
     }
-    if (!getKmsKeyBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(kmsKey_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(18, kmsKey_);
     }
     if (updateStorageClassTime_ != null) {
@@ -6623,7 +6623,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
      * In a response, this field will always be set to true or false.
      * </pre>
      *
-     * <code>bool event_based_hold = 23;</code>
+     * <code>optional bool event_based_hold = 23;</code>
      *
      * @return Whether the eventBasedHold field is set.
      */
@@ -6647,7 +6647,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
      * In a response, this field will always be set to true or false.
      * </pre>
      *
-     * <code>bool event_based_hold = 23;</code>
+     * <code>optional bool event_based_hold = 23;</code>
      *
      * @return The eventBasedHold.
      */
@@ -6671,7 +6671,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
      * In a response, this field will always be set to true or false.
      * </pre>
      *
-     * <code>bool event_based_hold = 23;</code>
+     * <code>optional bool event_based_hold = 23;</code>
      *
      * @param value The eventBasedHold to set.
      * @return This builder for chaining.
@@ -6698,7 +6698,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3
      * In a response, this field will always be set to true or false.
      * </pre>
      *
-     * <code>bool event_based_hold = 23;</code>
+     * <code>optional bool event_based_hold = 23;</code>
      *
      * @return This builder for chaining.
      */
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java
index 493188fb..e7ce2b1b 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java
@@ -550,22 +550,22 @@ public final class ObjectAccessControl extends com.google.protobuf.GeneratedMess
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getRoleBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(role_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, role_);
     }
-    if (!getIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 2, id_);
     }
-    if (!getEntityBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entity_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 3, entity_);
     }
-    if (!getEntityIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entityId_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 4, entityId_);
     }
-    if (!getEmailBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(email_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 5, email_);
     }
-    if (!getDomainBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(domain_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 6, domain_);
     }
     if (projectTeam_ != null) {
@@ -580,22 +580,22 @@ public final class ObjectAccessControl extends com.google.protobuf.GeneratedMess
     if (size != -1) return size;
 
     size = 0;
-    if (!getRoleBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(role_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, role_);
     }
-    if (!getIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, id_);
     }
-    if (!getEntityBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entity_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, entity_);
     }
-    if (!getEntityIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entityId_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, entityId_);
     }
-    if (!getEmailBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(email_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, email_);
     }
-    if (!getDomainBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(domain_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, domain_);
     }
     if (projectTeam_ != null) {
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java
index aac23454..b72dd842 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java
@@ -129,7 +129,7 @@ public final class ObjectChecksums extends com.google.protobuf.GeneratedMessageV
    * object matches this checksum.
    * </pre>
    *
-   * <code>fixed32 crc32c = 1;</code>
+   * <code>optional fixed32 crc32c = 1;</code>
    *
    * @return Whether the crc32c field is set.
    */
@@ -147,7 +147,7 @@ public final class ObjectChecksums extends com.google.protobuf.GeneratedMessageV
    * object matches this checksum.
    * </pre>
    *
-   * <code>fixed32 crc32c = 1;</code>
+   * <code>optional fixed32 crc32c = 1;</code>
    *
    * @return The crc32c.
    */
@@ -532,7 +532,7 @@ public final class ObjectChecksums extends com.google.protobuf.GeneratedMessageV
      * object matches this checksum.
      * </pre>
      *
-     * <code>fixed32 crc32c = 1;</code>
+     * <code>optional fixed32 crc32c = 1;</code>
      *
      * @return Whether the crc32c field is set.
      */
@@ -550,7 +550,7 @@ public final class ObjectChecksums extends com.google.protobuf.GeneratedMessageV
      * object matches this checksum.
      * </pre>
      *
-     * <code>fixed32 crc32c = 1;</code>
+     * <code>optional fixed32 crc32c = 1;</code>
      *
      * @return The crc32c.
      */
@@ -568,7 +568,7 @@ public final class ObjectChecksums extends com.google.protobuf.GeneratedMessageV
      * object matches this checksum.
      * </pre>
      *
-     * <code>fixed32 crc32c = 1;</code>
+     * <code>optional fixed32 crc32c = 1;</code>
      *
      * @param value The crc32c to set.
      * @return This builder for chaining.
@@ -589,7 +589,7 @@ public final class ObjectChecksums extends com.google.protobuf.GeneratedMessageV
      * object matches this checksum.
      * </pre>
      *
-     * <code>fixed32 crc32c = 1;</code>
+     * <code>optional fixed32 crc32c = 1;</code>
      *
      * @return This builder for chaining.
      */
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java
index aaddb753..f094b2b6 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java
@@ -33,7 +33,7 @@ public interface ObjectChecksumsOrBuilder
    * object matches this checksum.
    * </pre>
    *
-   * <code>fixed32 crc32c = 1;</code>
+   * <code>optional fixed32 crc32c = 1;</code>
    *
    * @return Whether the crc32c field is set.
    */
@@ -48,7 +48,7 @@ public interface ObjectChecksumsOrBuilder
    * object matches this checksum.
    * </pre>
    *
-   * <code>fixed32 crc32c = 1;</code>
+   * <code>optional fixed32 crc32c = 1;</code>
    *
    * @return The crc32c.
    */
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java
index 5938f154..08410519 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java
@@ -782,7 +782,7 @@ public interface ObjectOrBuilder
    * In a response, this field will always be set to true or false.
    * </pre>
    *
-   * <code>bool event_based_hold = 23;</code>
+   * <code>optional bool event_based_hold = 23;</code>
    *
    * @return Whether the eventBasedHold field is set.
    */
@@ -803,7 +803,7 @@ public interface ObjectOrBuilder
    * In a response, this field will always be set to true or false.
    * </pre>
    *
-   * <code>bool event_based_hold = 23;</code>
+   * <code>optional bool event_based_hold = 23;</code>
    *
    * @return The eventBasedHold.
    */
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java
index e97de659..c87862b6 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java
@@ -229,10 +229,10 @@ public final class Owner extends com.google.protobuf.GeneratedMessageV3
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getEntityBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entity_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, entity_);
     }
-    if (!getEntityIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entityId_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 2, entityId_);
     }
     unknownFields.writeTo(output);
@@ -244,10 +244,10 @@ public final class Owner extends com.google.protobuf.GeneratedMessageV3
     if (size != -1) return size;
 
     size = 0;
-    if (!getEntityBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entity_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, entity_);
     }
-    if (!getEntityIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(entityId_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, entityId_);
     }
     size += unknownFields.getSerializedSize();
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java
index 24386ea8..6d9d3065 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java
@@ -231,10 +231,10 @@ public final class ProjectTeam extends com.google.protobuf.GeneratedMessageV3
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getProjectNumberBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(projectNumber_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, projectNumber_);
     }
-    if (!getTeamBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(team_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 2, team_);
     }
     unknownFields.writeTo(output);
@@ -246,10 +246,10 @@ public final class ProjectTeam extends com.google.protobuf.GeneratedMessageV3
     if (size != -1) return size;
 
     size = 0;
-    if (!getProjectNumberBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(projectNumber_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, projectNumber_);
     }
-    if (!getTeamBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(team_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, team_);
     }
     size += unknownFields.getSerializedSize();
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java
index 33a6ad3e..eb93ce9a 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java
@@ -383,7 +383,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 6;</code>
+   * <code>optional int64 if_generation_match = 6;</code>
    *
    * @return Whether the ifGenerationMatch field is set.
    */
@@ -400,7 +400,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 6;</code>
+   * <code>optional int64 if_generation_match = 6;</code>
    *
    * @return The ifGenerationMatch.
    */
@@ -421,7 +421,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 7;</code>
+   * <code>optional int64 if_generation_not_match = 7;</code>
    *
    * @return Whether the ifGenerationNotMatch field is set.
    */
@@ -439,7 +439,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 7;</code>
+   * <code>optional int64 if_generation_not_match = 7;</code>
    *
    * @return The ifGenerationNotMatch.
    */
@@ -458,7 +458,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 8;</code>
+   * <code>optional int64 if_metageneration_match = 8;</code>
    *
    * @return Whether the ifMetagenerationMatch field is set.
    */
@@ -474,7 +474,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 8;</code>
+   * <code>optional int64 if_metageneration_match = 8;</code>
    *
    * @return The ifMetagenerationMatch.
    */
@@ -493,7 +493,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 9;</code>
+   * <code>optional int64 if_metageneration_not_match = 9;</code>
    *
    * @return Whether the ifMetagenerationNotMatch field is set.
    */
@@ -509,7 +509,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 9;</code>
+   * <code>optional int64 if_metageneration_not_match = 9;</code>
    *
    * @return The ifMetagenerationNotMatch.
    */
@@ -628,7 +628,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * * may be used to mean "all fields".
    * </pre>
    *
-   * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+   * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
    *
    * @return Whether the readMask field is set.
    */
@@ -647,7 +647,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * * may be used to mean "all fields".
    * </pre>
    *
-   * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+   * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
    *
    * @return The readMask.
    */
@@ -666,7 +666,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
    * * may be used to mean "all fields".
    * </pre>
    *
-   * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+   * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
    */
   @java.lang.Override
   public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() {
@@ -687,10 +687,10 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getBucketBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(bucket_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, bucket_);
     }
-    if (!getObjectBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(object_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 2, object_);
     }
     if (generation_ != 0L) {
@@ -732,10 +732,10 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
     if (size != -1) return size;
 
     size = 0;
-    if (!getBucketBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(bucket_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, bucket_);
     }
-    if (!getObjectBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(object_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, object_);
     }
     if (generation_ != 0L) {
@@ -1656,7 +1656,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 6;</code>
+     * <code>optional int64 if_generation_match = 6;</code>
      *
      * @return Whether the ifGenerationMatch field is set.
      */
@@ -1673,7 +1673,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 6;</code>
+     * <code>optional int64 if_generation_match = 6;</code>
      *
      * @return The ifGenerationMatch.
      */
@@ -1690,7 +1690,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 6;</code>
+     * <code>optional int64 if_generation_match = 6;</code>
      *
      * @param value The ifGenerationMatch to set.
      * @return This builder for chaining.
@@ -1710,7 +1710,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 6;</code>
+     * <code>optional int64 if_generation_match = 6;</code>
      *
      * @return This builder for chaining.
      */
@@ -1732,7 +1732,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 7;</code>
+     * <code>optional int64 if_generation_not_match = 7;</code>
      *
      * @return Whether the ifGenerationNotMatch field is set.
      */
@@ -1750,7 +1750,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 7;</code>
+     * <code>optional int64 if_generation_not_match = 7;</code>
      *
      * @return The ifGenerationNotMatch.
      */
@@ -1768,7 +1768,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 7;</code>
+     * <code>optional int64 if_generation_not_match = 7;</code>
      *
      * @param value The ifGenerationNotMatch to set.
      * @return This builder for chaining.
@@ -1789,7 +1789,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 7;</code>
+     * <code>optional int64 if_generation_not_match = 7;</code>
      *
      * @return This builder for chaining.
      */
@@ -1809,7 +1809,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 8;</code>
+     * <code>optional int64 if_metageneration_match = 8;</code>
      *
      * @return Whether the ifMetagenerationMatch field is set.
      */
@@ -1825,7 +1825,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 8;</code>
+     * <code>optional int64 if_metageneration_match = 8;</code>
      *
      * @return The ifMetagenerationMatch.
      */
@@ -1841,7 +1841,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 8;</code>
+     * <code>optional int64 if_metageneration_match = 8;</code>
      *
      * @param value The ifMetagenerationMatch to set.
      * @return This builder for chaining.
@@ -1860,7 +1860,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 8;</code>
+     * <code>optional int64 if_metageneration_match = 8;</code>
      *
      * @return This builder for chaining.
      */
@@ -1880,7 +1880,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 9;</code>
+     * <code>optional int64 if_metageneration_not_match = 9;</code>
      *
      * @return Whether the ifMetagenerationNotMatch field is set.
      */
@@ -1896,7 +1896,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 9;</code>
+     * <code>optional int64 if_metageneration_not_match = 9;</code>
      *
      * @return The ifMetagenerationNotMatch.
      */
@@ -1912,7 +1912,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 9;</code>
+     * <code>optional int64 if_metageneration_not_match = 9;</code>
      *
      * @param value The ifMetagenerationNotMatch to set.
      * @return This builder for chaining.
@@ -1931,7 +1931,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 9;</code>
+     * <code>optional int64 if_metageneration_not_match = 9;</code>
      *
      * @return This builder for chaining.
      */
@@ -2335,7 +2335,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      *
      * @return Whether the readMask field is set.
      */
@@ -2353,7 +2353,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      *
      * @return The readMask.
      */
@@ -2375,7 +2375,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      */
     public Builder setReadMask(com.google.protobuf.FieldMask value) {
       if (readMaskBuilder_ == null) {
@@ -2401,7 +2401,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      */
     public Builder setReadMask(com.google.protobuf.FieldMask.Builder builderForValue) {
       if (readMaskBuilder_ == null) {
@@ -2424,7 +2424,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      */
     public Builder mergeReadMask(com.google.protobuf.FieldMask value) {
       if (readMaskBuilder_ == null) {
@@ -2454,7 +2454,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      */
     public Builder clearReadMask() {
       if (readMaskBuilder_ == null) {
@@ -2477,7 +2477,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      */
     public com.google.protobuf.FieldMask.Builder getReadMaskBuilder() {
       bitField0_ |= 0x00000010;
@@ -2495,7 +2495,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      */
     public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() {
       if (readMaskBuilder_ != null) {
@@ -2515,7 +2515,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag
      * * may be used to mean "all fields".
      * </pre>
      *
-     * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+     * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
      */
     private com.google.protobuf.SingleFieldBuilderV3<
             com.google.protobuf.FieldMask,
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java
index bf9a6806..23a835ab 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java
@@ -134,7 +134,7 @@ public interface ReadObjectRequestOrBuilder
    * there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 6;</code>
+   * <code>optional int64 if_generation_match = 6;</code>
    *
    * @return Whether the ifGenerationMatch field is set.
    */
@@ -148,7 +148,7 @@ public interface ReadObjectRequestOrBuilder
    * there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 6;</code>
+   * <code>optional int64 if_generation_match = 6;</code>
    *
    * @return The ifGenerationMatch.
    */
@@ -164,7 +164,7 @@ public interface ReadObjectRequestOrBuilder
    * version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 7;</code>
+   * <code>optional int64 if_generation_not_match = 7;</code>
    *
    * @return Whether the ifGenerationNotMatch field is set.
    */
@@ -179,7 +179,7 @@ public interface ReadObjectRequestOrBuilder
    * version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 7;</code>
+   * <code>optional int64 if_generation_not_match = 7;</code>
    *
    * @return The ifGenerationNotMatch.
    */
@@ -193,7 +193,7 @@ public interface ReadObjectRequestOrBuilder
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 8;</code>
+   * <code>optional int64 if_metageneration_match = 8;</code>
    *
    * @return Whether the ifMetagenerationMatch field is set.
    */
@@ -206,7 +206,7 @@ public interface ReadObjectRequestOrBuilder
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 8;</code>
+   * <code>optional int64 if_metageneration_match = 8;</code>
    *
    * @return The ifMetagenerationMatch.
    */
@@ -220,7 +220,7 @@ public interface ReadObjectRequestOrBuilder
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 9;</code>
+   * <code>optional int64 if_metageneration_not_match = 9;</code>
    *
    * @return Whether the ifMetagenerationNotMatch field is set.
    */
@@ -233,7 +233,7 @@ public interface ReadObjectRequestOrBuilder
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 9;</code>
+   * <code>optional int64 if_metageneration_not_match = 9;</code>
    *
    * @return The ifMetagenerationNotMatch.
    */
@@ -320,7 +320,7 @@ public interface ReadObjectRequestOrBuilder
    * * may be used to mean "all fields".
    * </pre>
    *
-   * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+   * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
    *
    * @return Whether the readMask field is set.
    */
@@ -336,7 +336,7 @@ public interface ReadObjectRequestOrBuilder
    * * may be used to mean "all fields".
    * </pre>
    *
-   * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+   * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
    *
    * @return The readMask.
    */
@@ -352,7 +352,7 @@ public interface ReadObjectRequestOrBuilder
    * * may be used to mean "all fields".
    * </pre>
    *
-   * <code>.google.protobuf.FieldMask read_mask = 12;</code>
+   * <code>optional .google.protobuf.FieldMask read_mask = 12;</code>
    */
   com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder();
 }
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java
index 48f6f14e..98440f0e 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java
@@ -176,7 +176,7 @@ public final class StartResumableWriteResponse extends com.google.protobuf.Gener
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getUploadIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uploadId_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, uploadId_);
     }
     unknownFields.writeTo(output);
@@ -188,7 +188,7 @@ public final class StartResumableWriteResponse extends com.google.protobuf.Gener
     if (size != -1) return size;
 
     size = 0;
-    if (!getUploadIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uploadId_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, uploadId_);
     }
     size += unknownFields.getSerializedSize();
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java
index 8aa73d38..d1ef0a7a 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java
@@ -245,7 +245,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * succeed only if there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 3;</code>
+   * <code>optional int64 if_generation_match = 3;</code>
    *
    * @return Whether the ifGenerationMatch field is set.
    */
@@ -262,7 +262,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * succeed only if there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 3;</code>
+   * <code>optional int64 if_generation_match = 3;</code>
    *
    * @return The ifGenerationMatch.
    */
@@ -283,7 +283,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * there is a live version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 4;</code>
+   * <code>optional int64 if_generation_not_match = 4;</code>
    *
    * @return Whether the ifGenerationNotMatch field is set.
    */
@@ -301,7 +301,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * there is a live version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 4;</code>
+   * <code>optional int64 if_generation_not_match = 4;</code>
    *
    * @return The ifGenerationNotMatch.
    */
@@ -320,7 +320,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 5;</code>
+   * <code>optional int64 if_metageneration_match = 5;</code>
    *
    * @return Whether the ifMetagenerationMatch field is set.
    */
@@ -336,7 +336,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 5;</code>
+   * <code>optional int64 if_metageneration_match = 5;</code>
    *
    * @return The ifMetagenerationMatch.
    */
@@ -355,7 +355,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 6;</code>
+   * <code>optional int64 if_metageneration_not_match = 6;</code>
    *
    * @return Whether the ifMetagenerationNotMatch field is set.
    */
@@ -371,7 +371,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 6;</code>
+   * <code>optional int64 if_metageneration_not_match = 6;</code>
    *
    * @return The ifMetagenerationNotMatch.
    */
@@ -1102,7 +1102,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * succeed only if there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 3;</code>
+     * <code>optional int64 if_generation_match = 3;</code>
      *
      * @return Whether the ifGenerationMatch field is set.
      */
@@ -1119,7 +1119,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * succeed only if there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 3;</code>
+     * <code>optional int64 if_generation_match = 3;</code>
      *
      * @return The ifGenerationMatch.
      */
@@ -1136,7 +1136,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * succeed only if there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 3;</code>
+     * <code>optional int64 if_generation_match = 3;</code>
      *
      * @param value The ifGenerationMatch to set.
      * @return This builder for chaining.
@@ -1156,7 +1156,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * succeed only if there are no live versions of the object.
      * </pre>
      *
-     * <code>int64 if_generation_match = 3;</code>
+     * <code>optional int64 if_generation_match = 3;</code>
      *
      * @return This builder for chaining.
      */
@@ -1178,7 +1178,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * there is a live version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 4;</code>
+     * <code>optional int64 if_generation_not_match = 4;</code>
      *
      * @return Whether the ifGenerationNotMatch field is set.
      */
@@ -1196,7 +1196,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * there is a live version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 4;</code>
+     * <code>optional int64 if_generation_not_match = 4;</code>
      *
      * @return The ifGenerationNotMatch.
      */
@@ -1214,7 +1214,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * there is a live version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 4;</code>
+     * <code>optional int64 if_generation_not_match = 4;</code>
      *
      * @param value The ifGenerationNotMatch to set.
      * @return This builder for chaining.
@@ -1235,7 +1235,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * there is a live version of the object.
      * </pre>
      *
-     * <code>int64 if_generation_not_match = 4;</code>
+     * <code>optional int64 if_generation_not_match = 4;</code>
      *
      * @return This builder for chaining.
      */
@@ -1255,7 +1255,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 5;</code>
+     * <code>optional int64 if_metageneration_match = 5;</code>
      *
      * @return Whether the ifMetagenerationMatch field is set.
      */
@@ -1271,7 +1271,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 5;</code>
+     * <code>optional int64 if_metageneration_match = 5;</code>
      *
      * @return The ifMetagenerationMatch.
      */
@@ -1287,7 +1287,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 5;</code>
+     * <code>optional int64 if_metageneration_match = 5;</code>
      *
      * @param value The ifMetagenerationMatch to set.
      * @return This builder for chaining.
@@ -1306,7 +1306,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration matches the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_match = 5;</code>
+     * <code>optional int64 if_metageneration_match = 5;</code>
      *
      * @return This builder for chaining.
      */
@@ -1326,7 +1326,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 6;</code>
+     * <code>optional int64 if_metageneration_not_match = 6;</code>
      *
      * @return Whether the ifMetagenerationNotMatch field is set.
      */
@@ -1342,7 +1342,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 6;</code>
+     * <code>optional int64 if_metageneration_not_match = 6;</code>
      *
      * @return The ifMetagenerationNotMatch.
      */
@@ -1358,7 +1358,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 6;</code>
+     * <code>optional int64 if_metageneration_not_match = 6;</code>
      *
      * @param value The ifMetagenerationNotMatch to set.
      * @return This builder for chaining.
@@ -1377,7 +1377,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV
      * metageneration does not match the given value.
      * </pre>
      *
-     * <code>int64 if_metageneration_not_match = 6;</code>
+     * <code>optional int64 if_metageneration_not_match = 6;</code>
      *
      * @return This builder for chaining.
      */
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java
index 61c4426a..459b4e9c 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java
@@ -92,7 +92,7 @@ public interface WriteObjectSpecOrBuilder
    * succeed only if there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 3;</code>
+   * <code>optional int64 if_generation_match = 3;</code>
    *
    * @return Whether the ifGenerationMatch field is set.
    */
@@ -106,7 +106,7 @@ public interface WriteObjectSpecOrBuilder
    * succeed only if there are no live versions of the object.
    * </pre>
    *
-   * <code>int64 if_generation_match = 3;</code>
+   * <code>optional int64 if_generation_match = 3;</code>
    *
    * @return The ifGenerationMatch.
    */
@@ -122,7 +122,7 @@ public interface WriteObjectSpecOrBuilder
    * there is a live version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 4;</code>
+   * <code>optional int64 if_generation_not_match = 4;</code>
    *
    * @return Whether the ifGenerationNotMatch field is set.
    */
@@ -137,7 +137,7 @@ public interface WriteObjectSpecOrBuilder
    * there is a live version of the object.
    * </pre>
    *
-   * <code>int64 if_generation_not_match = 4;</code>
+   * <code>optional int64 if_generation_not_match = 4;</code>
    *
    * @return The ifGenerationNotMatch.
    */
@@ -151,7 +151,7 @@ public interface WriteObjectSpecOrBuilder
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 5;</code>
+   * <code>optional int64 if_metageneration_match = 5;</code>
    *
    * @return Whether the ifMetagenerationMatch field is set.
    */
@@ -164,7 +164,7 @@ public interface WriteObjectSpecOrBuilder
    * metageneration matches the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_match = 5;</code>
+   * <code>optional int64 if_metageneration_match = 5;</code>
    *
    * @return The ifMetagenerationMatch.
    */
@@ -178,7 +178,7 @@ public interface WriteObjectSpecOrBuilder
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 6;</code>
+   * <code>optional int64 if_metageneration_not_match = 6;</code>
    *
    * @return Whether the ifMetagenerationNotMatch field is set.
    */
@@ -191,7 +191,7 @@ public interface WriteObjectSpecOrBuilder
    * metageneration does not match the given value.
    * </pre>
    *
-   * <code>int64 if_metageneration_not_match = 6;</code>
+   * <code>optional int64 if_metageneration_not_match = 6;</code>
    *
    * @return The ifMetagenerationNotMatch.
    */
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index 4f56565a..d67d6c28 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -30,7 +30,7 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>23.1.0</version>
+        <version>24.0.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
diff --git a/synth.metadata b/synth.metadata
index 962316f5..cd426bb9 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -4,22 +4,22 @@
       "git": {
         "name": ".",
         "remote": "https://github.com/googleapis/java-storage.git",
-        "sha": "cdb86dcca17636ff7be59208361f8d42ab0858ba"
+        "sha": "c0185f4c42ff7f1a1f2d814c27cb4a9e3abd3460"
       }
     },
     {
       "git": {
         "name": "googleapis",
         "remote": "https://github.com/googleapis/googleapis.git",
-        "sha": "877d3d9d02591ad612a2c8654b42c37ba09ff9ec",
-        "internalRef": "402986756"
+        "sha": "d2977af9e9f1fc0c9dc8368352daa032471f3c63",
+        "internalRef": "403132955"
       }
     },
     {
       "git": {
         "name": "synthtool",
         "remote": "https://github.com/googleapis/synthtool.git",
-        "sha": "a4be3384ccb92364795d981f2863f6986fcee620"
+        "sha": "cb2755306975de4c54ea549c9deb25703b3731bb"
       }
     }
   ],
@@ -70,6 +70,7 @@
     ".kokoro/presubmit/clirr.cfg",
     ".kokoro/presubmit/common.cfg",
     ".kokoro/presubmit/dependencies.cfg",
+    ".kokoro/presubmit/graalvm-native.cfg",
     ".kokoro/presubmit/java11.cfg",
     ".kokoro/presubmit/java7.cfg",
     ".kokoro/presubmit/java8-osx.cfg",


Test patch:
diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/DefaultRetryHandlingBehaviorTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/DefaultRetryHandlingBehaviorTest.java
new file mode 100644
index 00000000..402430ce
--- /dev/null
+++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/DefaultRetryHandlingBehaviorTest.java
@@ -0,0 +1,919 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package com.google.cloud.storage;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import com.google.api.client.googleapis.json.GoogleJsonError;
+import com.google.api.client.http.HttpHeaders;
+import com.google.api.client.http.HttpResponseException;
+import com.google.api.gax.retrying.ResultRetryAlgorithm;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLProtocolException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Validate the behavior of our new "default" ResultRetryAlgorithms against that of the legacy retry
+ * handling behavior.
+ */
+@RunWith(Parameterized.class)
+public final class DefaultRetryHandlingBehaviorTest {
+  private static final String DEFAULT_MESSAGE = "err_default_message";
+
+  private final Case c;
+  private final DefaultStorageRetryStrategy defaultStrategy;
+  private final StorageRetryStrategy legacyStrategy;
+
+  @SuppressWarnings("deprecation")
+  public DefaultRetryHandlingBehaviorTest(Case c) {
+    this.c = c;
+    defaultStrategy = new DefaultStorageRetryStrategy();
+    legacyStrategy = StorageRetryStrategy.getLegacyStorageRetryStrategy();
+  }
+
+  /**
+   * For a specified {@link Case}
+   *
+   * <ol>
+   *   <li>Resolve the ResultRetryAlgorithm for the specific {@link HandlerCategory} for both
+   *       default and legacy
+   *   <li>Evaluate the retryability of the throwable {@link Case#getThrowable()} against both of
+   *       the resolved {@code ResultRetryAlgorithm}s
+   *   <li>Resolve the {@link Behavior} change if any between the two evaluation results
+   *   <li>Assert the behavior change matches the {@link Case#expectedBehavior expected behavior}
+   * </ol>
+   */
+  @SuppressWarnings("ConstantConditions")
+  @Test
+  public void validateBehavior() {
+    ResultRetryAlgorithm<?> defaultAlgorithm = c.handlerCategory.apply(defaultStrategy);
+    ResultRetryAlgorithm<?> legacyAlgorithm = c.handlerCategory.apply(legacyStrategy);
+    Throwable throwable = c.getThrowable();
+
+    boolean defaultShouldRetryResult = defaultAlgorithm.shouldRetry(throwable, null);
+    boolean legacyShouldRetryResult = legacyAlgorithm.shouldRetry(throwable, null);
+
+    Behavior actualBehavior = null;
+    String message = null;
+    boolean shouldRetry = c.getExpectRetry().shouldRetry;
+    if (shouldRetry && !defaultShouldRetryResult && legacyShouldRetryResult) {
+      actualBehavior = Behavior.DEFAULT_MORE_STRICT;
+      message = "default is more strict";
+    } else if (shouldRetry && !defaultShouldRetryResult && !legacyShouldRetryResult) {
+      actualBehavior = Behavior.SAME;
+      message = "both are rejecting when we want a retry";
+    } else if (shouldRetry && defaultShouldRetryResult && legacyShouldRetryResult) {
+      actualBehavior = Behavior.SAME;
+      message = "both are allowing";
+    } else if (shouldRetry && defaultShouldRetryResult && !legacyShouldRetryResult) {
+      actualBehavior = Behavior.DEFAULT_MORE_PERMISSIBLE;
+      message = "default is more permissive";
+    } else if (!shouldRetry && !defaultShouldRetryResult && legacyShouldRetryResult) {
+      actualBehavior = Behavior.DEFAULT_MORE_STRICT;
+      message = "default is more strict";
+    } else if (!shouldRetry && !defaultShouldRetryResult && !legacyShouldRetryResult) {
+      actualBehavior = Behavior.SAME;
+      message = "both are rejecting as expected";
+    } else if (!shouldRetry && defaultShouldRetryResult && legacyShouldRetryResult) {
+      actualBehavior = Behavior.SAME;
+      message = "both are too permissive";
+    } else if (!shouldRetry && defaultShouldRetryResult && !legacyShouldRetryResult) {
+      actualBehavior = Behavior.DEFAULT_MORE_PERMISSIBLE;
+      message = "default is too permissive";
+    }
+
+    assertWithMessage(message).that(actualBehavior).isEqualTo(c.expectedBehavior);
+  }
+
+  /** Resolve all the test cases and assert all permutations have a case defined. */
+  @Parameters(name = "{0}")
+  public static Collection<Object[]> testCases() {
+
+    // define the list of cases to be validated
+    List<Case> cases = getAllCases();
+
+    /* perform validation of the defined list of cases to ensure all permutations are defined */
+
+    // calculate all the possible permutations
+    ImmutableSet<String> expectedTokens =
+        Arrays.stream(HandlerCategory.values())
+            .flatMap(
+                handlerCategory ->
+                    Arrays.stream(ThrowableCategory.values())
+                        .map(throwableCategory -> token(throwableCategory, handlerCategory)))
+            .collect(toImmutableSet());
+
+    // calculate the actual defined permutations
+    ImmutableSet<String> actualTokens =
+        cases.stream()
+            .map(c -> token(c.throwableCategory, c.handlerCategory))
+            .collect(toImmutableSet());
+
+    // calculate the difference if any between expected and actual, then sort and listify
+    ImmutableList<String> difference =
+        Sets.difference(expectedTokens, actualTokens).stream().sorted().collect(toImmutableList());
+
+    // ensure all permutations are accounted for, reporting any that haven't been and providing
+    // a stub which can be used to easily define them.
+    assertWithMessage("Missing mappings for tokens").that(difference).isEmpty();
+
+    // wrap our case in an array for ultimate passing to the constructor
+    return cases.stream().map(c -> new Object[] {c}).collect(toImmutableList());
+  }
+
+  /**
+   * Generate a token which represents a permutation for which a {@link Case} must be defined.
+   *
+   * <p>If a case is not defined, this value will be reported and functions as a stub to easily
+   * define a new {@code Case}.
+   */
+  private static String token(ThrowableCategory t, HandlerCategory h) {
+    return String.format(
+        "new Case(ThrowableCategory.%s, HandlerCategory.%s, /*TODO*/ null, /*TODO*/ null)",
+        t.name(), h.name());
+  }
+
+  /**
+   * An individual case we want to validate.
+   *
+   * <p>Given a {@link HandlerCategory} and {@link ThrowableCategory} validate the retryability and
+   * behavior between default and legacy handlers.
+   */
+  static final class Case {
+
+    private final HandlerCategory handlerCategory;
+    private final ThrowableCategory throwableCategory;
+    private final ExpectRetry expectRetry;
+    private final Behavior expectedBehavior;
+
+    Case(
+        ThrowableCategory throwableCategory,
+        HandlerCategory handlerCategory,
+        ExpectRetry expectRetry,
+        Behavior expectedBehavior) {
+      this.handlerCategory = handlerCategory;
+      this.throwableCategory = throwableCategory;
+      this.expectRetry = expectRetry;
+      this.expectedBehavior = expectedBehavior;
+    }
+
+    Throwable getThrowable() {
+      return throwableCategory.throwable;
+    }
+
+    public ExpectRetry getExpectRetry() {
+      return expectRetry;
+    }
+
+    @Override
+    public String toString() {
+      return "Case{"
+          + "handlerCategory="
+          + handlerCategory
+          + ", throwableCategory="
+          + throwableCategory
+          + ", expectRetry="
+          + expectRetry
+          + ", expectedBehavior="
+          + expectedBehavior
+          + '}';
+    }
+  }
+
+  /** Whether to expect a retry to happen or not */
+  enum ExpectRetry {
+    YES(true),
+    NO(false);
+
+    private final boolean shouldRetry;
+
+    ExpectRetry(boolean shouldRetry) {
+      this.shouldRetry = shouldRetry;
+    }
+  }
+
+  /**
+   * A category of handler type, and the ability to resolve the {@link ResultRetryAlgorithm} given a
+   * {@link StorageRetryStrategy}
+   */
+  enum HandlerCategory implements Function<StorageRetryStrategy, ResultRetryAlgorithm<?>> {
+    IDEMPOTENT,
+    NONIDEMPOTENT;
+
+    @Override
+    public ResultRetryAlgorithm<?> apply(StorageRetryStrategy storageRetryStrategy) {
+      switch (this) {
+        case IDEMPOTENT:
+          return storageRetryStrategy.getIdempotentHandler();
+        case NONIDEMPOTENT:
+          return storageRetryStrategy.getNonidempotentHandler();
+        default:
+          throw new IllegalStateException("Unmappable HandlerCategory: " + this.name());
+      }
+    }
+  }
+
+  /** Some states comparing behavior between default and legacy */
+  enum Behavior {
+    DEFAULT_MORE_PERMISSIBLE,
+    SAME,
+    DEFAULT_MORE_STRICT
+  }
+
+  /**
+   * A set of exceptions we want to validate behavior for.
+   *
+   * <p>This class is an enum for convenience of specifying a closed set, along with providing easy
+   * to read names in code thereby forgoing the need to maintain a separate set of strings.
+   */
+  enum ThrowableCategory {
+    SOCKET_TIMEOUT_EXCEPTION(C.SOCKET_TIMEOUT_EXCEPTION),
+    SOCKET_EXCEPTION(C.SOCKET_EXCEPTION),
+    SSL_EXCEPTION(C.SSL_EXCEPTION),
+    SSL_EXCEPTION_CONNECTION_SHUTDOWN(C.SSL_EXCEPTION_CONNECTION_SHUTDOWN),
+    SSL_HANDSHAKE_EXCEPTION(C.SSL_HANDSHAKE_EXCEPTION),
+    SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION(
+        C.SSL_HANDSHAKE_EXCEPTION_CERTIFICATE_EXCEPTION),
+    INSUFFICIENT_DATA(C.INSUFFICIENT_DATA_WRITTEN),
+    ERROR_WRITING_REQUEST_BODY(C.ERROR_WRITING_REQUEST_BODY),
+    HTTP_RESPONSE_EXCEPTION_401(C.HTTP_401),
+    HTTP_RESPONSE_EXCEPTION_403(C.HTTP_403),
+    HTTP_RESPONSE_EXCEPTION_404(C.HTTP_404),
+    HTTP_RESPONSE_EXCEPTION_408(C.HTTP_409),
+    HTTP_RESPONSE_EXCEPTION_429(C.HTTP_429),
+    HTTP_RESPONSE_EXCEPTION_500(C.HTTP_500),
+    HTTP_RESPONSE_EXCEPTION_502(C.HTTP_502),
+    HTTP_RESPONSE_EXCEPTION_503(C.HTTP_503),
+    HTTP_RESPONSE_EXCEPTION_504(C.HTTP_504),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_401(new StorageException(C.HTTP_401)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_403(new StorageException(C.HTTP_403)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_404(new StorageException(C.HTTP_404)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_408(new StorageException(C.HTTP_409)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_429(new StorageException(C.HTTP_429)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_500(new StorageException(C.HTTP_500)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_502(new StorageException(C.HTTP_502)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_503(new StorageException(C.HTTP_503)),
+    STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_504(new StorageException(C.HTTP_504)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_401(new StorageException(C.JSON_401)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_403(new StorageException(C.JSON_403)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_404(new StorageException(C.JSON_404)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_408(new StorageException(C.JSON_408)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_429(new StorageException(C.JSON_429)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500(new StorageException(C.JSON_500)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_502(new StorageException(C.JSON_502)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_503(new StorageException(C.JSON_503)),
+    STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_504(new StorageException(C.JSON_504)),
+    STORAGE_EXCEPTION_SOCKET_TIMEOUT_EXCEPTION(new StorageException(C.SOCKET_TIMEOUT_EXCEPTION)),
+    STORAGE_EXCEPTION_SOCKET_EXCEPTION(new StorageException(C.SOCKET_EXCEPTION)),
+    STORAGE_EXCEPTION_SSL_EXCEPTION(new StorageException(C.SSL_EXCEPTION)),
+    STORAGE_EXCEPTION_SSL_EXCEPTION_CONNECTION_SHUTDOWN(
+        new StorageException(C.SSL_EXCEPTION_CONNECTION_SHUTDOWN)),
+    STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION(new StorageException(C.SSL_HANDSHAKE_EXCEPTION)),
+    STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION(
+        new StorageException(C.SSL_HANDSHAKE_EXCEPTION_CERTIFICATE_EXCEPTION)),
+    STORAGE_EXCEPTION_INSUFFICIENT_DATA(new StorageException(C.INSUFFICIENT_DATA_WRITTEN)),
+    STORAGE_EXCEPTION_ERROR_WRITING_REQUEST_BODY(
+        new StorageException(C.ERROR_WRITING_REQUEST_BODY)),
+    ILLEGAL_ARGUMENT_EXCEPTION(C.ILLEGAL_ARGUMENT_EXCEPTION),
+    STORAGE_EXCEPTION_ILLEGAL_ARGUMENT_EXCEPTION(
+        StorageException.coalesce(C.ILLEGAL_ARGUMENT_EXCEPTION)),
+    STORAGE_EXCEPTION_0_INTERNAL_ERROR(
+        new StorageException(0, "internalError", "internalError", null)),
+    STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY(
+        new StorageException(
+            0, "connectionClosedPrematurely", "connectionClosedPrematurely", null)),
+    STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE(
+        new StorageException(
+            0,
+            "connectionClosedPrematurely",
+            "connectionClosedPrematurely",
+            C.CONNECTION_CLOSED_PREMATURELY)),
+    ;
+
+    private final Throwable throwable;
+
+    ThrowableCategory(Throwable throwable) {
+      this.throwable = throwable;
+    }
+
+    public Throwable getThrowable() {
+      return throwable;
+    }
+
+    /**
+     * A class of constants for use by the containing enum.
+     *
+     * <p>Enums can't have static fields, so we use this class to hold constants which are used by
+     * the enum values.
+     */
+    private static final class C {
+      private static final SocketTimeoutException SOCKET_TIMEOUT_EXCEPTION =
+          new SocketTimeoutException();
+      private static final SocketException SOCKET_EXCEPTION = new SocketException();
+      private static final SSLException SSL_EXCEPTION = new SSLException("unknown");
+      private static final SSLException SSL_EXCEPTION_CONNECTION_SHUTDOWN =
+          new SSLException("Connection has been shutdown: asdf");
+      private static final SSLHandshakeException SSL_HANDSHAKE_EXCEPTION =
+          newSslHandshakeExceptionWithCause(new SSLProtocolException(DEFAULT_MESSAGE));
+      private static final SSLHandshakeException SSL_HANDSHAKE_EXCEPTION_CERTIFICATE_EXCEPTION =
+          newSslHandshakeExceptionWithCause(new CertificateException());
+      private static final IOException INSUFFICIENT_DATA_WRITTEN =
+          new IOException("insufficient data written");
+      private static final IOException ERROR_WRITING_REQUEST_BODY =
+          new IOException("Error writing request body to server");
+      private static final HttpResponseException HTTP_401 =
+          newHttpResponseException(401, "Unauthorized");
+      private static final HttpResponseException HTTP_403 =
+          newHttpResponseException(403, "Forbidden");
+      private static final HttpResponseException HTTP_404 =
+          newHttpResponseException(404, "Not Found");
+      private static final HttpResponseException HTTP_409 =
+          newHttpResponseException(408, "Request Timeout");
+      private static final HttpResponseException HTTP_429 =
+          newHttpResponseException(429, "Too Many Requests");
+      private static final HttpResponseException HTTP_500 =
+          newHttpResponseException(500, "Internal Server Error");
+      private static final HttpResponseException HTTP_502 =
+          newHttpResponseException(502, "Bad Gateway");
+      private static final HttpResponseException HTTP_503 =
+          newHttpResponseException(503, "Service Unavailable");
+      private static final HttpResponseException HTTP_504 =
+          newHttpResponseException(504, "Gateway Timeout");
+      private static final GoogleJsonError JSON_401 = newGoogleJsonError(401, "Unauthorized");
+      private static final GoogleJsonError JSON_403 = newGoogleJsonError(403, "Forbidden");
+      private static final GoogleJsonError JSON_404 = newGoogleJsonError(404, "Not Found");
+      private static final GoogleJsonError JSON_408 = newGoogleJsonError(408, "Request Timeout");
+      private static final GoogleJsonError JSON_429 = newGoogleJsonError(429, "Too Many Requests");
+      private static final GoogleJsonError JSON_500 =
+          newGoogleJsonError(500, "Internal Server Error");
+      private static final GoogleJsonError JSON_502 = newGoogleJsonError(502, "Bad Gateway");
+      private static final GoogleJsonError JSON_503 =
+          newGoogleJsonError(503, "Service Unavailable");
+      private static final GoogleJsonError JSON_504 = newGoogleJsonError(504, "Gateway Timeout");
+      private static final IllegalArgumentException ILLEGAL_ARGUMENT_EXCEPTION =
+          new IllegalArgumentException("illegal argument");
+      private static final IOException CONNECTION_CLOSED_PREMATURELY =
+          new IOException("simulated Connection closed prematurely");
+
+      private static HttpResponseException newHttpResponseException(
+          int httpStatusCode, String name) {
+        return new HttpResponseException.Builder(httpStatusCode, name, new HttpHeaders()).build();
+      }
+
+      private static GoogleJsonError newGoogleJsonError(int code, String message) {
+        GoogleJsonError error = new GoogleJsonError();
+        error.setCode(code);
+        error.setMessage(message);
+        return error;
+      }
+
+      private static SSLHandshakeException newSslHandshakeExceptionWithCause(Throwable cause) {
+        SSLHandshakeException sslHandshakeException = new SSLHandshakeException(DEFAULT_MESSAGE);
+        Throwable throwable = sslHandshakeException.initCause(cause);
+        return (SSLHandshakeException) throwable;
+      }
+    }
+  }
+
+  /**
+   * A corralled method which allows us to move the individual cases away from the rest of the code
+   * since our code formatter is very strict and seems to feel 475 lines of code at 100 columns is
+   * better than 90 lines at 200 columns.
+   *
+   * <p>this method returns a list that essentially is a table of where each row is an individual
+   * test case
+   *
+   * <table>
+   *   <tr>
+   *     <th>{@link ThrowableCategory throwable category}</th>
+   *     <th>{@link HandlerCategory handler category}</th>
+   *     <th>{@link ExpectRetry whether retry is expected}</th>
+   *     <th>{@link Behavior what the expected behavior comparison is}</th>
+   *   </tr>
+   *   <tr>
+   *     <td>{@link ThrowableCategory#STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500 STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500}</td>
+   *     <td>{@link HandlerCategory#NONIDEMPOTENT NONIDEMPOTENT}</td>
+   *     <td>{@link ExpectRetry#NO NO}</td>
+   *     <td>{@link Behavior#DEFAULT_MORE_STRICT DEFAULT_MORE_STRICT}</td>
+   *   </tr>
+   * </table>
+   */
+  private static ImmutableList<Case> getAllCases() {
+    return ImmutableList.<Case>builder()
+        .add(
+            new Case(
+                ThrowableCategory.ERROR_WRITING_REQUEST_BODY,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.ERROR_WRITING_REQUEST_BODY,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_401,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_401,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_403,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_403,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_404,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_404,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_408,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_408,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_429,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_429,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_500,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_500,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_502,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_502,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_503,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_503,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_504,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.HTTP_RESPONSE_EXCEPTION_504,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.ILLEGAL_ARGUMENT_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.ILLEGAL_ARGUMENT_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.INSUFFICIENT_DATA,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.INSUFFICIENT_DATA,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SOCKET_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.SOCKET_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SOCKET_TIMEOUT_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.SOCKET_TIMEOUT_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SSL_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SSL_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SSL_EXCEPTION_CONNECTION_SHUTDOWN,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.SSL_EXCEPTION_CONNECTION_SHUTDOWN,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.DEFAULT_MORE_PERMISSIBLE),
+            new Case(
+                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_ERROR_WRITING_REQUEST_BODY,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_ERROR_WRITING_REQUEST_BODY,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_401,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_401,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_403,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_403,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_404,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_404,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_408,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_408,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_429,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_429,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_500,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_502,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_502,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_503,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_503,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_504,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_GOOGLE_JSON_ERROR_504,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_401,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_401,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_403,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_403,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_404,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_404,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_408,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_408,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_429,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_429,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_500,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_500,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_502,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_502,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_503,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_503,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_504,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_HTTP_RESPONSE_EXCEPTION_504,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_ILLEGAL_ARGUMENT_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_ILLEGAL_ARGUMENT_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_INSUFFICIENT_DATA,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_INSUFFICIENT_DATA,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_TIMEOUT_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SOCKET_TIMEOUT_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION_CONNECTION_SHUTDOWN,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SSL_EXCEPTION_CONNECTION_SHUTDOWN,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory
+                    .STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory
+                    .STORAGE_EXCEPTION_SSL_HANDSHAKE_EXCEPTION_CAUSED_BY_CERTIFICATE_EXCEPTION,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_0_CONNECTION_CLOSED_PREMATURELY_IO_CAUSE,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_0_INTERNAL_ERROR,
+                HandlerCategory.IDEMPOTENT,
+                ExpectRetry.YES,
+                Behavior.SAME),
+            new Case(
+                ThrowableCategory.STORAGE_EXCEPTION_0_INTERNAL_ERROR,
+                HandlerCategory.NONIDEMPOTENT,
+                ExpectRetry.NO,
+                Behavior.DEFAULT_MORE_STRICT))
+        .build();
+  }
+}
diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RetryTestFixture.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RetryTestFixture.java
index 7da69853..8be2db85 100644
--- a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RetryTestFixture.java
+++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RetryTestFixture.java
@@ -18,6 +18,7 @@ package com.google.cloud.storage.conformance.retry;
 
 import static org.junit.Assert.assertTrue;
 
+import com.google.api.gax.retrying.RetrySettings;
 import com.google.api.gax.rpc.FixedHeaderProvider;
 import com.google.cloud.NoCredentials;
 import com.google.cloud.conformance.storage.v1.InstructionList;
@@ -141,6 +142,8 @@ final class RetryTestFixture implements TestRule {
             .setCredentials(NoCredentials.getInstance())
             .setProjectId(testRetryConformance.getProjectId());
     builder = PackagePrivateMethodWorkarounds.useDefaultStorageRetryStrategy(builder);
+    RetrySettings.Builder retrySettingsBuilder =
+        StorageOptions.getDefaultRetrySettings().toBuilder();
     if (forTest) {
       builder
           .setHeaderProvider(
@@ -148,23 +151,26 @@ final class RetryTestFixture implements TestRule {
                 @Override
                 public Map<String, String> getHeaders() {
                   return ImmutableMap.of(
-                      "x-retry-test-id", retryTest.id, "User-Agent", "java-conformance-tests/");
+                      "x-retry-test-id", retryTest.id, "User-Agent", fmtUserAgent("test"));
                 }
               })
-          .setRetrySettings(
-              StorageOptions.getDefaultRetrySettings().toBuilder().setMaxAttempts(3).build());
+          .setRetrySettings(retrySettingsBuilder.setMaxAttempts(3).build());
     } else {
       builder
           .setHeaderProvider(
               new FixedHeaderProvider() {
                 @Override
                 public Map<String, String> getHeaders() {
-                  return ImmutableMap.of("User-Agent", "java-conformance-tests/");
+                  return ImmutableMap.of("User-Agent", fmtUserAgent("non-test"));
                 }
               })
-          .setRetrySettings(
-              StorageOptions.getDefaultRetrySettings().toBuilder().setMaxAttempts(1).build());
+          .setRetrySettings(retrySettingsBuilder.setMaxAttempts(1).build());
     }
     return builder.build().getService();
   }
+
+  private String fmtUserAgent(String testDescriptor) {
+    return String.format(
+        "%s/ (%s) java-conformance-tests/", testDescriptor, testRetryConformance.getTestName());
+  }
 }
diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/TestBench.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/TestBench.java
index c5642f9a..af79ffe7 100644
--- a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/TestBench.java
+++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/TestBench.java
@@ -92,7 +92,7 @@ final class TestBench implements TestRule {
                 request -> {
                   request.setCurlLoggingEnabled(false);
                   request.getHeaders().setAccept("application/json");
-                  request.getHeaders().setUserAgent("java-conformance-tests/");
+                  request.getHeaders().setUserAgent("test-bench/ java-conformance-tests/");
                 });
   }
 
diff --git a/google-cloud-storage/src/test/resources/com/google/cloud/storage/conformance/retry/testNamesWhichCanFail.txt b/google-cloud-storage/src/test/resources/com/google/cloud/storage/conformance/retry/testNamesWhichCanFail.txt
index 683f4c09..e0957997 100644
--- a/google-cloud-storage/src/test/resources/com/google/cloud/storage/conformance/retry/testNamesWhichCanFail.txt
+++ b/google-cloud-storage/src/test/resources/com/google/cloud/storage/conformance/retry/testNamesWhichCanFail.txt
@@ -5,12 +5,3 @@
 #    mvn -Penable-integration-test clean verify && xq '//testsuite/testcase[./error or ./failure]/@name' google-cloud-storage/target/failsafe-reports/TEST-com.google.cloud.storage.conformance.retry.ITRetryConformanceTest-sponge_log.xml | tail -n+2 | head -n-1 | sed 's#  <result>test\[##g' | sed 's#\]</result>##g' | sort | tee -a google-cloud-storage/src/test/resources/com/google/cloud/storage/conformance/retry/testNamesWhichCanFail.txt
 # where xq is the package from https://github.com/jeffbr13/xq
 
-TestRetryConformance/3-[return-reset-connection]-storage.objects.delete-36
-TestRetryConformance/3-[return-reset-connection]-storage.objects.delete-67
-TestRetryConformance/4-[return-reset-connection]-storage.bucket_acl.delete-1
-TestRetryConformance/4-[return-reset-connection]-storage.bucket_acl.delete-2
-TestRetryConformance/4-[return-reset-connection]-storage.bucket_acl.delete-87
-TestRetryConformance/4-[return-reset-connection]-storage.default_object_acl.delete-102
-TestRetryConformance/4-[return-reset-connection]-storage.default_object_acl.delete-20
-TestRetryConformance/4-[return-reset-connection]-storage.object_acl.delete-30
-TestRetryConformance/4-[return-reset-connection]-storage.object_acl.delete-62
diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java
index a3d479d6..027368ff 100644
--- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java
+++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java
@@ -305,7 +305,7 @@ public final class QueryWriteStatusRequest extends com.google.protobuf.Generated
 
   @java.lang.Override
   public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-    if (!getUploadIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uploadId_)) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 1, uploadId_);
     }
     if (commonObjectRequestParams_ != null) {
@@ -323,7 +323,7 @@ public final class QueryWriteStatusRequest extends com.google.protobuf.Generated
     if (size != -1) return size;
 
     size = 0;
-    if (!getUploadIdBytes().isEmpty()) {
+    if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(uploadId_)) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, uploadId_);
     }
     if (commonObjectRequestParams_ != null) {