Search in sources :

Example 96 with RecordMetaData

use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTestV3 method enumChanged.

/**
 * Enums are different with proto3 syntax. In particular, they require one of their values have value 0,
 * and they introduce an "UNKNOWN" value all of the time.
 */
@Test
public void enumChanged() {
    RecordMetaData metaData1 = RecordMetaData.build(TestRecordsEnumProtoV3.getDescriptor());
    FileDescriptor updatedFile = mutateEnum(enumType -> enumType.addValue(DescriptorProtos.EnumValueDescriptorProto.newBuilder().setName("X_LARGE").setNumber(4)));
    assertNotNull(updatedFile.findMessageTypeByName("MyShapeRecord").findEnumTypeByName("Size").findValueByName("X_LARGE"));
    RecordMetaData metaData2 = replaceRecordsDescriptor(metaData1, updatedFile);
    MetaDataEvolutionValidator.getDefaultInstance().validate(metaData1, metaData2);
    updatedFile = mutateEnum(enumType -> enumType.getValueBuilderList().forEach(enumValue -> {
        if (enumValue.getName().equals("SMALL")) {
            enumValue.setName("PETIT");
        }
    }));
    assertNotNull(updatedFile.findMessageTypeByName("MyShapeRecord").findEnumTypeByName("Size").findValueByName("PETIT"));
    metaData2 = replaceRecordsDescriptor(metaData1, updatedFile);
    MetaDataEvolutionValidator.getDefaultInstance().validate(metaData1, metaData2);
    updatedFile = mutateEnum(enumType -> enumType.removeValue(enumType.getValueCount() - 1));
    assertNull(updatedFile.findMessageTypeByName("MyShapeRecord").findEnumTypeByName("Size").findValueByName("LARGE"));
    metaData2 = replaceRecordsDescriptor(metaData1, updatedFile);
    assertInvalid("enum removes value", metaData1, metaData2);
}
Also used : DescriptorProtos(com.google.protobuf.DescriptorProtos) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) DynamicMessage(com.google.protobuf.DynamicMessage) TestRecords3Proto(com.apple.foundationdb.record.TestRecords3Proto) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) TestRecords3ProtoV3(com.apple.foundationdb.record.evolution.TestRecords3ProtoV3) TestRecordsNestedProto3(com.apple.foundationdb.record.evolution.TestRecordsNestedProto3) TestRecordsNestedProto2(com.apple.foundationdb.record.evolution.TestRecordsNestedProto2) TestRecordsEnumProtoV3(com.apple.foundationdb.record.evolution.TestRecordsEnumProtoV3) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Nonnull(javax.annotation.Nonnull) MetaDataEvolutionValidatorTest.replaceRecordsDescriptor(com.apple.foundationdb.record.metadata.MetaDataEvolutionValidatorTest.replaceRecordsDescriptor) TestRecords1ImportedProto(com.apple.foundationdb.record.evolution.TestRecords1ImportedProto) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) TestNestedProto3(com.apple.foundationdb.record.evolution.TestNestedProto3) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) Test(org.junit.jupiter.api.Test) Consumer(java.util.function.Consumer) Message(com.google.protobuf.Message) MetaDataEvolutionValidatorTest.assertInvalid(com.apple.foundationdb.record.metadata.MetaDataEvolutionValidatorTest.assertInvalid) Matchers.is(org.hamcrest.Matchers.is) MetaDataEvolutionValidatorTest.mutateFile(com.apple.foundationdb.record.metadata.MetaDataEvolutionValidatorTest.mutateFile) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Test(org.junit.jupiter.api.Test)

Example 97 with RecordMetaData

use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method enumFieldChanged.

@Test
public void enumFieldChanged() {
    // Add an enum field
    FileDescriptor updatedFile = mutateFile(TestRecordsEnumProto.getDescriptor(), fileBuilder -> fileBuilder.getMessageTypeBuilderList().forEach(message -> {
        if (message.getName().equals("MyShapeRecord")) {
            message.getEnumTypeBuilderList().forEach(enumType -> {
                if (enumType.getName().equals("Size")) {
                    enumType.addValue(DescriptorProtos.EnumValueDescriptorProto.newBuilder().setName("X_LARGE").setNumber(TestRecordsEnumProto.MyShapeRecord.Size.getDescriptor().getValues().stream().mapToInt(Descriptors.EnumValueDescriptor::getNumber).max().getAsInt() + 1));
                }
            });
        }
    }));
    validator.validateUnion(TestRecordsEnumProto.RecordTypeUnion.getDescriptor(), updatedFile.findMessageTypeByName(RecordMetaDataBuilder.DEFAULT_UNION_NAME));
    RecordMetaData metaData1 = RecordMetaData.build(TestRecordsEnumProto.getDescriptor());
    RecordMetaData metaData2 = replaceRecordsDescriptor(metaData1, updatedFile);
    validator.validate(metaData1, metaData2);
    // Dropping a value is not allowed
    assertInvalid("enum removes value", updatedFile, TestRecordsEnumProto.getDescriptor());
    RecordMetaData metaData3 = RecordMetaData.build(updatedFile);
    RecordMetaData metaData4 = replaceRecordsDescriptor(metaData3, TestRecordsEnumProto.getDescriptor());
    assertInvalid("enum removes value", metaData3, metaData4);
    // Changing the value name is okay
    updatedFile = mutateFile(TestRecordsEnumProto.getDescriptor(), fileBuilder -> fileBuilder.getEnumTypeBuilderList().forEach(enumType -> {
        if (enumType.getName().equals("Size")) {
            enumType.getValueBuilder(0).setName("PETIT");
        }
    }));
    validator.validateUnion(TestRecordsEnumProto.RecordTypeUnion.getDescriptor(), updatedFile.findMessageTypeByName(RecordMetaDataBuilder.DEFAULT_UNION_NAME));
    RecordMetaData metaData5 = replaceRecordsDescriptor(metaData1, updatedFile);
    validator.validate(metaData1, metaData5);
}
Also used : DescriptorProtos(com.google.protobuf.DescriptorProtos) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Arrays(java.util.Arrays) Descriptor(com.google.protobuf.Descriptors.Descriptor) Descriptors(com.google.protobuf.Descriptors) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) PrefixTextTokenizer(com.apple.foundationdb.record.provider.common.text.PrefixTextTokenizer) UnaryOperator(java.util.function.UnaryOperator) TestSplitNestedTypesProto(com.apple.foundationdb.record.evolution.TestSplitNestedTypesProto) TestNewRecordTypeProto(com.apple.foundationdb.record.evolution.TestNewRecordTypeProto) TestSelfReferenceUnspooledProto(com.apple.foundationdb.record.evolution.TestSelfReferenceUnspooledProto) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) RecordMetaDataOptionsProto(com.apple.foundationdb.record.RecordMetaDataOptionsProto) DefaultTextTokenizer(com.apple.foundationdb.record.provider.common.text.DefaultTextTokenizer) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) TestSelfReferenceProto(com.apple.foundationdb.record.evolution.TestSelfReferenceProto) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) TestUnmergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestUnmergedNestedTypesProto) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) Test(org.junit.jupiter.api.Test) Consumer(java.util.function.Consumer) TextTokenizer(com.apple.foundationdb.record.provider.common.text.TextTokenizer) List(java.util.List) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) TestHeaderAsGroupProto(com.apple.foundationdb.record.evolution.TestHeaderAsGroupProto) RankedSet(com.apple.foundationdb.async.RankedSet) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.is(org.hamcrest.Matchers.is) TestMergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestMergedNestedTypesProto) Collections(java.util.Collections) Matchers.containsString(org.hamcrest.Matchers.containsString) AllSuffixesTextTokenizer(com.apple.foundationdb.record.provider.common.text.AllSuffixesTextTokenizer) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Test(org.junit.jupiter.api.Test)

Example 98 with RecordMetaData

use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method removeFormerIndex.

// Former index tests
@Test
public void removeFormerIndex() {
    RecordMetaDataBuilder metaData1Builder = RecordMetaData.newBuilder().setRecords(TestRecords1Proto.getDescriptor());
    metaData1Builder.removeIndex("MySimpleRecord$str_value_indexed");
    RecordMetaData metaData1 = metaData1Builder.getRecordMetaData();
    RecordMetaData metaData2 = RecordMetaData.build(metaData1.toProto().toBuilder().setVersion(metaData1.getVersion() + 1).clearFormerIndexes().build());
    assertInvalid("former index removed", metaData1, metaData2);
}
Also used : RecordMetaData(com.apple.foundationdb.record.RecordMetaData) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) Test(org.junit.jupiter.api.Test)

Example 99 with RecordMetaData

use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method swapUnionFields.

// Protobuf evolution tests
@Test
public void swapUnionFields() {
    FileDescriptor updatedDescriptor = mutateFile(fileBuilder -> fileBuilder.getMessageTypeBuilderList().forEach(message -> {
        if (message.getName().equals(RecordMetaDataBuilder.DEFAULT_UNION_NAME)) {
            message.getFieldBuilderList().forEach(field -> {
                if (field.getNumber() == 1) {
                    field.setNumber(2);
                } else {
                    field.setNumber(1);
                }
            });
        }
    }));
    // The two record types do not have the same form, so swapping them should fail.
    // However, the exact way they fail isn't super important.
    RecordMetaData metaData1 = RecordMetaData.build(TestRecords1Proto.getDescriptor());
    RecordMetaData metaData2 = replaceRecordsDescriptor(metaData1, updatedDescriptor);
    assertInvalid("", metaData1, metaData2);
}
Also used : DescriptorProtos(com.google.protobuf.DescriptorProtos) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Arrays(java.util.Arrays) Descriptor(com.google.protobuf.Descriptors.Descriptor) Descriptors(com.google.protobuf.Descriptors) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) PrefixTextTokenizer(com.apple.foundationdb.record.provider.common.text.PrefixTextTokenizer) UnaryOperator(java.util.function.UnaryOperator) TestSplitNestedTypesProto(com.apple.foundationdb.record.evolution.TestSplitNestedTypesProto) TestNewRecordTypeProto(com.apple.foundationdb.record.evolution.TestNewRecordTypeProto) TestSelfReferenceUnspooledProto(com.apple.foundationdb.record.evolution.TestSelfReferenceUnspooledProto) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) RecordMetaDataOptionsProto(com.apple.foundationdb.record.RecordMetaDataOptionsProto) DefaultTextTokenizer(com.apple.foundationdb.record.provider.common.text.DefaultTextTokenizer) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) TestSelfReferenceProto(com.apple.foundationdb.record.evolution.TestSelfReferenceProto) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) TestUnmergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestUnmergedNestedTypesProto) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) Test(org.junit.jupiter.api.Test) Consumer(java.util.function.Consumer) TextTokenizer(com.apple.foundationdb.record.provider.common.text.TextTokenizer) List(java.util.List) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) TestHeaderAsGroupProto(com.apple.foundationdb.record.evolution.TestHeaderAsGroupProto) RankedSet(com.apple.foundationdb.async.RankedSet) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.is(org.hamcrest.Matchers.is) TestMergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestMergedNestedTypesProto) Collections(java.util.Collections) Matchers.containsString(org.hamcrest.Matchers.containsString) AllSuffixesTextTokenizer(com.apple.foundationdb.record.provider.common.text.AllSuffixesTextTokenizer) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Test(org.junit.jupiter.api.Test)

Example 100 with RecordMetaData

use of com.apple.foundationdb.record.RecordMetaData in project fdb-record-layer by FoundationDB.

the class MetaDataEvolutionValidatorTest method fieldTypeChanged.

@Test
public void fieldTypeChanged() throws InvalidProtocolBufferException {
    FileDescriptor updatedFile = mutateField("MySimpleRecord", "str_value_indexed", field -> field.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_BYTES));
    assertInvalid("field type changed", TestRecords1Proto.getDescriptor(), updatedFile);
    RecordMetaData metaData1 = RecordMetaData.build(TestRecords1Proto.getDescriptor());
    RecordMetaData metaData2 = replaceRecordsDescriptor(metaData1, updatedFile);
    assertInvalid("field type changed", metaData1, metaData2);
    // Allow int32 -> int64 but not int64 -> int32
    assertEquals(FieldDescriptor.Type.INT32, TestRecords1Proto.MySimpleRecord.getDescriptor().findFieldByName("num_value_2").getType());
    updatedFile = mutateField("MySimpleRecord", "num_value_2", field -> field.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_INT64));
    assertEquals(FieldDescriptor.Type.INT64, updatedFile.findMessageTypeByName("MySimpleRecord").findFieldByName("num_value_2").getType());
    validator.validateUnion(TestRecords1Proto.RecordTypeUnion.getDescriptor(), updatedFile.findMessageTypeByName(RecordMetaDataBuilder.DEFAULT_UNION_NAME));
    assertInvalid("field type changed", updatedFile, TestRecords1Proto.getDescriptor());
    RecordMetaData metaData3 = replaceRecordsDescriptor(metaData1, updatedFile);
    validator.validate(metaData1, metaData3);
    // Allow sint32 -> sint64 but not sint32 -> sint64
    FileDescriptor intermediateFile = mutateField("MySimpleRecord", "num_value_2", field -> field.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_SINT32));
    updatedFile = mutateField("MySimpleRecord", "num_value_2", field -> field.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_SINT64));
    validator.validateUnion(intermediateFile.findMessageTypeByName(RecordMetaDataBuilder.DEFAULT_UNION_NAME), updatedFile.findMessageTypeByName(RecordMetaDataBuilder.DEFAULT_UNION_NAME));
    assertInvalid("field type changed", updatedFile, intermediateFile);
    // Do not allow sfixed32 -> sfixed64
    intermediateFile = mutateField("MySimpleRecord", "num_value_2", field -> field.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_SFIXED32));
    updatedFile = mutateField("MySimpleRecord", "num_value_2", field -> field.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_SFIXED64));
    assertInvalid("field type changed", intermediateFile, updatedFile);
}
Also used : DescriptorProtos(com.google.protobuf.DescriptorProtos) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Arrays(java.util.Arrays) Descriptor(com.google.protobuf.Descriptors.Descriptor) Descriptors(com.google.protobuf.Descriptors) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) PrefixTextTokenizer(com.apple.foundationdb.record.provider.common.text.PrefixTextTokenizer) UnaryOperator(java.util.function.UnaryOperator) TestSplitNestedTypesProto(com.apple.foundationdb.record.evolution.TestSplitNestedTypesProto) TestNewRecordTypeProto(com.apple.foundationdb.record.evolution.TestNewRecordTypeProto) TestSelfReferenceUnspooledProto(com.apple.foundationdb.record.evolution.TestSelfReferenceUnspooledProto) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) RecordMetaDataProto(com.apple.foundationdb.record.RecordMetaDataProto) RecordMetaDataOptionsProto(com.apple.foundationdb.record.RecordMetaDataOptionsProto) DefaultTextTokenizer(com.apple.foundationdb.record.provider.common.text.DefaultTextTokenizer) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) TestSelfReferenceProto(com.apple.foundationdb.record.evolution.TestSelfReferenceProto) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) RecordMetaDataBuilder(com.apple.foundationdb.record.RecordMetaDataBuilder) TestUnmergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestUnmergedNestedTypesProto) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) Test(org.junit.jupiter.api.Test) Consumer(java.util.function.Consumer) TextTokenizer(com.apple.foundationdb.record.provider.common.text.TextTokenizer) List(java.util.List) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) TestHeaderAsGroupProto(com.apple.foundationdb.record.evolution.TestHeaderAsGroupProto) RankedSet(com.apple.foundationdb.async.RankedSet) TestRecordsEnumProto(com.apple.foundationdb.record.TestRecordsEnumProto) TestRecordsWithHeaderProto(com.apple.foundationdb.record.TestRecordsWithHeaderProto) Matchers.is(org.hamcrest.Matchers.is) TestMergedNestedTypesProto(com.apple.foundationdb.record.evolution.TestMergedNestedTypesProto) Collections(java.util.Collections) Matchers.containsString(org.hamcrest.Matchers.containsString) AllSuffixesTextTokenizer(com.apple.foundationdb.record.provider.common.text.AllSuffixesTextTokenizer) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) FileDescriptor(com.google.protobuf.Descriptors.FileDescriptor) Test(org.junit.jupiter.api.Test)

Aggregations

RecordMetaData (com.apple.foundationdb.record.RecordMetaData)168 Test (org.junit.jupiter.api.Test)130 RecordMetaDataBuilder (com.apple.foundationdb.record.RecordMetaDataBuilder)81 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)66 Nonnull (javax.annotation.Nonnull)47 Descriptors (com.google.protobuf.Descriptors)44 RecordMetaDataProto (com.apple.foundationdb.record.RecordMetaDataProto)39 MetaDataException (com.apple.foundationdb.record.metadata.MetaDataException)39 MetaDataProtoTest (com.apple.foundationdb.record.metadata.MetaDataProtoTest)38 Tuple (com.apple.foundationdb.tuple.Tuple)36 List (java.util.List)33 ArrayList (java.util.ArrayList)31 TestRecords1Proto (com.apple.foundationdb.record.TestRecords1Proto)30 Index (com.apple.foundationdb.record.metadata.Index)30 DescriptorProtos (com.google.protobuf.DescriptorProtos)30 Collectors (java.util.stream.Collectors)30 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)27 ByteString (com.google.protobuf.ByteString)27 Assertions.assertNotNull (org.junit.jupiter.api.Assertions.assertNotNull)27 RecordMetaDataOptionsProto (com.apple.foundationdb.record.RecordMetaDataOptionsProto)26