MetaDataProtoEditor { @Nonnull private static FieldTypeMatch fieldIsType(@Nonnull String namespace, @Nonnull DescriptorProtos.DescriptorProtoOrBuilder message, @Nonnull DescriptorProtos.FieldDescriptorProtoOrBuilder field, @Nonnull String fullTypeName) { final String messageNamespace; if (namespace.isEmpty()) { messageNamespace = message.getName(); } else { messageNamespace = namespace + "." + message.getName(); } if (field.hasTypeName() && !field.getTypeName().isEmpty()) { final String fieldTypeName = field.getTypeName(); if (fieldTypeName.startsWith(".")) { if (fieldTypeName.equals(fullTypeName)) { return FieldTypeMatch.MATCHES; } else if (fieldTypeName.startsWith(fullTypeName) && fieldTypeName.charAt(fullTypeName.length()) == '.') { return FieldTypeMatch.MATCHES_AS_NESTED; } } else { String[] fullTypeParts = fullTypeName.substring(1).split("\\."); String[] messageNamespaceParts = messageNamespace.split("\\."); String[] typeNameParts = fieldTypeName.split("\\."); for (int n = messageNamespaceParts.length; n >= 0; n--) { int fullTypePos = 0; boolean namespaceMatches = true; for (int i = 0; i < n && fullTypePos < fullTypeParts.length; i++, fullTypePos++) { if (!fullTypeParts[fullTypePos].equals(messageNamespaceParts[i])) { namespaceMatches = false; break; } } if (!namespaceMatches) { continue; } int typeNamePos = 0; while (typeNamePos < typeNameParts.length && fullTypePos < fullTypeParts.length) { if (!fullTypeParts[fullTypePos].equals(typeNameParts[typeNamePos])) { break; } typeNamePos++; fullTypePos++; } if (fullTypePos == fullTypeParts.length) { if (typeNamePos == typeNameParts.length) { return FieldTypeMatch.MIGHT_MATCH; } else { return FieldTypeMatch.MIGHT_MATCH_AS_NESTED; } } } } return FieldTypeMatch.DOES_NOT_MATCH; } else { return FieldTypeMatch.DOES_NOT_MATCH; } }  static void addRecordType(@Nonnull RecordMetaDataProto.MetaData.Builder metaDataBuilder, @Nonnull DescriptorProtos.DescriptorProto newRecordType, @Nonnull KeyExpression primaryKey); static void addNestedRecordType(@Nonnull RecordMetaDataProto.MetaData.Builder metaDataBuilder, @Nonnull DescriptorProtos.DescriptorProto newRecordType); static void deprecateRecordType(@Nonnull RecordMetaDataProto.MetaData.Builder metaDataBuilder, @Nonnull String recordType); static void renameRecordType(@Nonnull RecordMetaDataProto.MetaData.Builder metaDataBuilder,
                                        @Nonnull String recordTypeName, @Nonnull String newRecordTypeName); static void addField(@Nonnull RecordMetaDataProto.MetaData.Builder metaDataBuilder, @Nonnull String recordType, @Nonnull DescriptorProtos.FieldDescriptorProto field); static void deprecateField(@Nonnull RecordMetaDataProto.MetaData.Builder metaDataBuilder, @Nonnull String recordType, @Nonnull String fieldName); @Nonnull static Descriptors.FileDescriptor addDefaultUnionIfMissing(@Nonnull Descriptors.FileDescriptor fileDescriptor); @Nonnull static Descriptors.FileDescriptor addDefaultUnionIfMissing(@Nonnull Descriptors.FileDescriptor fileDescriptor, @Nonnull Descriptors.Descriptor baseUnionDescriptor); @Nonnull @API(API.Status.INTERNAL) static DescriptorProtos.DescriptorProto.Builder createSyntheticUnion(@Nonnull Descriptors.FileDescriptor fileDescriptor, @Nonnull Descriptors.Descriptor baseUnionDescriptor); static boolean hasUnion(@Nonnull Descriptors.FileDescriptor fileDescriptor);  }
@Test public void fieldIsType() { final DescriptorProtos.FileDescriptorProto file = TestRecords1Proto.getDescriptor().toProto(); assertEquals(FieldTypeMatch.MATCHES, fieldIsType(file, RecordMetaDataBuilder.DEFAULT_UNION_NAME, "_MySimpleRecord", "MySimpleRecord")); assertEquals(FieldTypeMatch.MATCHES, fieldIsType(file, RecordMetaDataBuilder.DEFAULT_UNION_NAME, "_MySimpleRecord", ".com.apple.foundationdb.record.test1.MySimpleRecord")); assertEquals(FieldTypeMatch.MATCHES_AS_NESTED, fieldIsType(file, RecordMetaDataBuilder.DEFAULT_UNION_NAME, "_MySimpleRecord", ".com.apple.foundationdb.record")); assertEquals(FieldTypeMatch.DOES_NOT_MATCH, fieldIsType(file, RecordMetaDataBuilder.DEFAULT_UNION_NAME, "_MySimpleRecord", "MySimpleRecord.MyNestedRecord")); assertEquals(FieldTypeMatch.DOES_NOT_MATCH, fieldIsType(file, RecordMetaDataBuilder.DEFAULT_UNION_NAME, "_MySimpleRecord", ".com.apple.foundationdb.record.test1.MySimpleRecord.MyNestedRecord")); assertEquals(FieldTypeMatch.DOES_NOT_MATCH, fieldIsType(file, RecordMetaDataBuilder.DEFAULT_UNION_NAME, "_MySimpleRecord", ".com.apple.foundationdb.record.test2.MySimpleRecord")); assertEquals(FieldTypeMatch.DOES_NOT_MATCH, fieldIsType(file, RecordMetaDataBuilder.DEFAULT_UNION_NAME, "_MySimpleRecord", "MyOtherRecord")); }
@Test public void nestedFieldIsType() { final DescriptorProtos.FileDescriptorProto file = TestRecordsDoubleNestedProto.getDescriptor().toProto(); assertEquals(FieldTypeMatch.MATCHES, fieldIsType(file, "OuterRecord", "inner", "OuterRecord.MiddleRecord.InnerRecord")); assertEquals(FieldTypeMatch.MATCHES, fieldIsType(file, "OuterRecord", "inner", ".com.apple.foundationdb.record.test.doublenested.OuterRecord.MiddleRecord.InnerRecord")); assertEquals(FieldTypeMatch.MATCHES_AS_NESTED, fieldIsType(file, "OuterRecord", "inner", "OuterRecord")); assertEquals(FieldTypeMatch.MATCHES_AS_NESTED, fieldIsType(file, "OuterRecord", "inner", "OuterRecord.MiddleRecord")); assertEquals(FieldTypeMatch.MATCHES_AS_NESTED, fieldIsType(file, "OuterRecord", "inner", ".com.apple.foundationdb.record.test.doublenested.OuterRecord")); assertEquals(FieldTypeMatch.MATCHES_AS_NESTED, fieldIsType(file, "OuterRecord", "inner", ".com.apple.foundationdb.record.test.doublenested.OuterRecord.MiddleRecord")); assertEquals(FieldTypeMatch.MATCHES, fieldIsType(file, "MiddleRecord", "middle", "MiddleRecord")); assertEquals(FieldTypeMatch.DOES_NOT_MATCH, fieldIsType(file, "MiddleRecord", "middle", "OuterRecord.MiddleRecord")); assertEquals(FieldTypeMatch.DOES_NOT_MATCH, fieldIsType(file, "MiddleRecord", "other_middle", "MiddleRecord")); assertEquals(FieldTypeMatch.MATCHES, fieldIsType(file, "MiddleRecord", "other_middle", "OuterRecord.MiddleRecord")); }