public Schema toSnakeCase() {
    return this.getFields().stream()
        .map(
            field -> {
              FieldType innerType = field.getType();
              if (innerType.getRowSchema() != null) {
                Schema innerSnakeCaseSchema = innerType.getRowSchema().toSnakeCase();
                innerType = innerType.toBuilder().setRowSchema(innerSnakeCaseSchema).build();
                field = field.toBuilder().setType(innerType).build();
              }
              return field
                  .toBuilder()
                  .setName(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()))
                  .build();
            })
        .collect(toSchema());
  }
@Test
  public void testToSnakeCase() {
    Schema innerSchema =
        Schema.builder()
            .addStringField("myFirstNestedStringField")
            .addStringField("mySecondNestedStringField")
            .build();
    Schema schema =
        Schema.builder()
            .addStringField("myFirstStringField")
            .addStringField("mySecondStringField")
            .addRowField("myRowField", innerSchema)
            .build();

    Schema expectedInnerSnakeCaseSchema =
        Schema.builder()
            .addStringField("my_first_nested_string_field")
            .addStringField("my_second_nested_string_field")
            .build();
    Schema expectedSnakeCaseSchema =
        Schema.builder()
            .addStringField("my_first_string_field")
            .addStringField("my_second_string_field")
            .addRowField("my_row_field", expectedInnerSnakeCaseSchema)
            .build();

    assertEquals(
        expectedInnerSnakeCaseSchema,
        schema.toSnakeCase().getField("my_row_field").getType().getRowSchema());
    assertEquals(expectedSnakeCaseSchema, schema.toSnakeCase());
  }