下面列出了怎么用com.google.protobuf.Descriptors的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Get the value of the field with the given field name on the given message.
* If the field is repeated, the repeated values are combined into a list. If the field has a message type,
* the value is returned as a {@link Message} of that type. Otherwise, the field is returned as a primitive.
* @param message a message or builder to extract the field from
* @param fieldName the field to extract
* @return the value of the field as described above
*/
@Nullable
public static Object getFieldOnMessage(@Nonnull MessageOrBuilder message, @Nonnull String fieldName) {
final Descriptors.FieldDescriptor field = findFieldDescriptorOnMessage(message, fieldName);
if (field.isRepeated()) {
int count = message.getRepeatedFieldCount(field);
List<Object> list = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
list.add(message.getRepeatedField(field, i));
}
return list;
}
if (field.hasDefaultValue() || message.hasField(field)) {
if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE &&
TupleFieldsHelper.isTupleField(field.getMessageType())) {
return TupleFieldsHelper.fromProto((Message)message.getField(field), field.getMessageType());
} else {
return message.getField(field);
}
} else {
return null;
}
}
private void fillUnionFields(boolean processExtensionOptions) {
if (unionDescriptor == null) {
throw new RecordCoreException("cannot fill union fiends as no union descriptor has been set");
}
if (!unionFields.isEmpty()) {
throw new RecordCoreException("cannot set union fields twice");
}
for (Descriptors.FieldDescriptor unionField : unionDescriptor.getFields()) {
Descriptors.Descriptor descriptor = unionField.getMessageType();
if (!unionFields.containsKey(descriptor)) {
processRecordType(unionField, processExtensionOptions);
unionFields.put(descriptor, unionField);
} else {
// The preferred field is the last one, except if there is one whose name matches.
remapUnionField(descriptor, unionField);
}
}
}
private EnumValueChangeInfo diffEnumValue(
Descriptors.EnumValueDescriptor f_ref, Descriptors.EnumValueDescriptor f_new) {
diffOptionsFromEnumValue(f_ref, f_new);
EnumValueChangeInfo.Builder builder = EnumValueChangeInfo.newBuilder();
if (!f_ref.getName().equals(f_new.getName())) {
builder.setChangeType(ChangeType.CHANGED);
builder.setFromName(f_ref.getName());
builder.setToName(f_new.getName());
}
if (isDeprecated(f_ref) != isDeprecated(f_new)) {
builder.setChangeType(ChangeType.CHANGED);
builder.setFromDeprecated(isDeprecated(f_ref));
builder.setToDeprecated(isDeprecated(f_new));
}
if (builder.getChangeType().equals(ChangeType.CHANGED)) {
return builder.build();
}
return null;
}
@Override
public DataParser getParser(String id, InputStream is, String offset) throws DataParserException {
try {
return new ProtobufDataParser(
getSettings().getContext(),
id,
descriptor,
messageTypeToExtensionMap,
extensionRegistry,
is,
offset,
getSettings().getOverRunLimit(),
isDelimited
);
} catch (IOException | Descriptors.DescriptorValidationException e) {
throw new DataParserException(Errors.DATA_PARSER_01, e.toString(), e);
}
}
/**
* Constructs a named {@code Message} from a {@code .desc} file into a {@code Descriptor}.
* <p>
* This will parse the {@code .desc} file and then extract the encapsulated
* {@link com.google.protobuf.Descriptors.Descriptor} the designated {@link Message} from the resulting parent
* {@link Descriptors.FileDescriptor}.
*
* @param filePath the location of the .desc file
* @param messageName the name of the Message
* @return the constructed Descriptor
*/
public static Descriptors.Descriptor buildDescriptor(String filePath, String messageName) {
Descriptors.FileDescriptor fileDescriptor = parseFileDescriptor(filePath);
Descriptors.Descriptor result = null;
for (Descriptors.Descriptor descriptor : fileDescriptor.getMessageTypes()) {
if (descriptor.getName().equals(messageName)) {
result = descriptor;
}
}
if (null == result) {
throw new RuntimeException("Unable to locate Message '" + messageName + "' in Descriptor");
}
return result;
}
private String getParsingInfo(T protoMessageInstance) {
List<ProtoBufParsingInfo> protoBufParsingInfos = new LinkedList<>();
protoMessageInstance.getDescriptorForType().getFields().forEach(new Consumer<Descriptors.FieldDescriptor>() {
@Override
public void accept(Descriptors.FieldDescriptor fieldDescriptor) {
protoBufParsingInfos.add(new ProtoBufParsingInfo(fieldDescriptor.getNumber(),
fieldDescriptor.getName(), fieldDescriptor.getType().name(),
fieldDescriptor.toProto().getLabel().name(), null));
}
});
try {
return new ObjectMapper().writeValueAsString(protoBufParsingInfos);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
* Retrieves and converts Protobuf fields from a Message.
* <p>
* If the field in the {@link com.google.protobuf.Descriptors.Descriptor} exists in the {@link Message}, the value is
* retrieved and converted using {@link #getFieldValue(Descriptors.FieldDescriptor, Object, DataType)}.
* Otherwise, the field value is {@code null}.
* The extraction honors the order of the {@code Descriptor}.
*
* @param dsc the Protobuf Descriptor with all fields
* @param msg the Message with the current field values
* @param schema the Dataset schema derived from the Descriptor
* @return a list of converted values
*/
public static List<Object> buildRowValues(Descriptors.Descriptor dsc, Message msg, StructType schema) {
List<Object> values = new ArrayList<>();
Object val;
for (Descriptors.FieldDescriptor fd : dsc.getFields()) {
if ( (!fd.isRepeated() && msg.hasField(fd)) || (fd.isRepeated() && msg.getRepeatedFieldCount(fd) > 0) ) {
val = getFieldValue(fd, msg.getField(fd), schema.apply(fd.getName()).dataType());
} else {
LOG.trace("FieldDescriptor[{}] => not found", fd.getFullName());
val = null;
}
values.add(val);
}
return values;
}
public Collection<Descriptors.EnumDescriptor> findEnumDescriptorsByOption(String optionName) {
Descriptors.FieldDescriptor fieldDescriptor = optionsCatalog.getEnumOptionByName(optionName);
return enumMap.values().stream()
.filter(
descriptor -> {
DescriptorProtos.EnumOptions options = descriptor.getOptions();
UnknownFieldSet.Field unknown =
options.getUnknownFields().getField(fieldDescriptor.getNumber());
if (unknown.getLengthDelimitedList().size()
+ unknown.getFixed64List().size()
+ unknown.getFixed32List().size()
+ unknown.getVarintList().size()
> 0) {
return true;
}
return options.getAllFields().containsKey(fieldDescriptor);
})
.collect(Collectors.toList());
}
@SuppressWarnings("unchecked")
@Override
public Mono<Void> write(Publisher<? extends Message> inputStream, ResolvableType elementType,
@Nullable MediaType mediaType, ReactiveHttpOutputMessage message, Map<String, Object> hints) {
try {
Message.Builder builder = getMessageBuilder(elementType.toClass());
Descriptors.Descriptor descriptor = builder.getDescriptorForType();
message.getHeaders().add(X_PROTOBUF_SCHEMA_HEADER, descriptor.getFile().getName());
message.getHeaders().add(X_PROTOBUF_MESSAGE_HEADER, descriptor.getFullName());
if (inputStream instanceof Flux) {
if (mediaType == null) {
message.getHeaders().setContentType(((HttpMessageEncoder<?>)getEncoder()).getStreamingMediaTypes().get(0));
}
else if (!ProtobufEncoder.DELIMITED_VALUE.equals(mediaType.getParameters().get(ProtobufEncoder.DELIMITED_KEY))) {
Map<String, String> parameters = new HashMap<>(mediaType.getParameters());
parameters.put(ProtobufEncoder.DELIMITED_KEY, ProtobufEncoder.DELIMITED_VALUE);
message.getHeaders().setContentType(new MediaType(mediaType.getType(), mediaType.getSubtype(), parameters));
}
}
return super.write(inputStream, elementType, mediaType, message, hints);
}
catch (Exception ex) {
return Mono.error(new DecodingException("Could not read Protobuf message: " + ex.getMessage(), ex));
}
}
private static void validateInnerRecordsInRightPlaces(@Nonnull RecordMetaData metaData) {
Descriptors.FileDescriptor recordsDescriptor = metaData.getRecordsDescriptor();
Descriptors.Descriptor innerRecord = recordsDescriptor.findMessageTypeByName("InnerRecord");
assertNotNull(innerRecord);
Descriptors.Descriptor outerRecord = recordsDescriptor.findMessageTypeByName("OuterRecord");
assertNotNull(outerRecord);
Descriptors.Descriptor middleRecord = outerRecord.findNestedTypeByName("MiddleRecord");
assertNotNull(middleRecord);
Descriptors.Descriptor nestedInnerRecord = middleRecord.findNestedTypeByName("InnerRecord");
assertNotNull(nestedInnerRecord);
Descriptors.FieldDescriptor innerField = outerRecord.findFieldByName("inner");
assertSame(nestedInnerRecord, innerField.getMessageType());
assertNotSame(innerRecord, innerField.getMessageType());
Descriptors.FieldDescriptor nestedInnerField = outerRecord.findFieldByName("inner");
assertSame(nestedInnerRecord, nestedInnerField.getMessageType());
assertNotSame(innerRecord, nestedInnerField.getMessageType());
}
private void dumpValue(DynamicMessage.Builder builder, Descriptors.FieldDescriptor fd, Object val) {
if (JavaType.ENUM == fd.getJavaType()) {
Descriptors.EnumValueDescriptor enum_val = null;
if (val instanceof Descriptors.EnumValueDescriptor) {
enum_val = (Descriptors.EnumValueDescriptor) val;
} else {
val = get_enum_value(cachePbs, fd.getEnumType(), (Integer) val);
}
if (null == enum_val) {
return;
}
if (fd.isRepeated()) {
builder.addRepeatedField(fd, enum_val);
} else {
builder.setField(fd, enum_val);
}
} else {
if (fd.isRepeated()) {
builder.addRepeatedField(fd, val);
} else {
builder.setField(fd, val);
}
}
}
static public Map<Descriptors.FieldDescriptor, Object> getFields(MessageOrBuilder message, boolean withDefaultValue) {
if (!withDefaultValue) {
return message.getAllFields();
}
Map<Descriptors.FieldDescriptor, Object> fieldsToPrint = new LinkedHashMap<>();
for (Descriptors.FieldDescriptor field : message.getDescriptorForType().getFields()) {
if (field.isOptional()) {
if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE && !message.hasField(field)) {
continue;
}
// if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.STRING && !message.hasField(field)) {
// continue;
// }
}
fieldsToPrint.put(field, message.getField(field));
}
return fieldsToPrint;
}
private static Descriptors.Descriptor marshalDescriptor(String desc) {
DescriptorProtos.FileDescriptorSet fileDescriptorSet;
try (BufferedInputStream dscFile = new BufferedInputStream(new FileInputStream(
TestProtobufUtils.class.getResource(desc).getPath()
))) {
fileDescriptorSet = DescriptorProtos.FileDescriptorSet.parseFrom(dscFile);
} catch (Throwable throwable) {
throw new RuntimeException("Unable to construct test resources", throwable);
}
// Get the attached .proto file
DescriptorProtos.FileDescriptorProto descriptorProto = fileDescriptorSet.getFile(0);
try {
Descriptors.FileDescriptor fileDescriptor = Descriptors.FileDescriptor.buildFrom(descriptorProto,
new Descriptors.FileDescriptor[]{});
if (fileDescriptor.getMessageTypes().isEmpty()) {
throw new RuntimeException("No MessageTypes returned, " + fileDescriptor.getName());
}
return fileDescriptor.getMessageTypes().get(0);
} catch (Descriptors.DescriptorValidationException e) {
throw new RuntimeException("Error constructing FileDescriptor", e);
}
}
public ListConverter(Message.Builder parentBuilder, Descriptors.FieldDescriptor fieldDescriptor, Type parquetType) {
LogicalTypeAnnotation logicalTypeAnnotation = parquetType.getLogicalTypeAnnotation();
if (!(logicalTypeAnnotation instanceof LogicalTypeAnnotation.ListLogicalTypeAnnotation) || parquetType.isPrimitive()) {
throw new ParquetDecodingException("Expected LIST wrapper. Found: " + logicalTypeAnnotation + " instead.");
}
GroupType rootWrapperType = parquetType.asGroupType();
if (!rootWrapperType.containsField("list") || rootWrapperType.getType("list").isPrimitive()) {
throw new ParquetDecodingException("Expected repeated 'list' group inside LIST wrapperr but got: " + rootWrapperType);
}
GroupType listType = rootWrapperType.getType("list").asGroupType();
if (!listType.containsField("element")) {
throw new ParquetDecodingException("Expected 'element' inside repeated list group but got: " + listType);
}
Type elementType = listType.getType("element");
converter = newMessageConverter(parentBuilder, fieldDescriptor, elementType);
}
public DataVerifyPbOneof(Descriptors.OneofDescriptor desc) {
super(desc.getName());
for (Descriptors.FieldDescriptor fd : desc.getFields()) {
all_names.put(fd.getName(), (long) fd.getNumber());
all_numbers.add((long) fd.getNumber());
// alias extension
if (fd.getOptions().hasExtension(Xresloader.fieldAlias)) {
String alias_name = fd.getOptions().getExtension(Xresloader.fieldAlias);
if (!alias_name.isEmpty()) {
all_names.put(alias_name, (long) fd.getNumber());
}
}
}
}
private void writeOptionForBlock(
Descriptors.FieldDescriptor fieldDescriptor, Object value, int indent, String optionType) {
indent(indent);
writer.print("option ");
if (fieldDescriptor.getFullName().startsWith("google.protobuf." + optionType + "Options")) {
writer.print(fieldDescriptor.getName());
} else {
writer.print("(");
writer.print(fieldDescriptor.getFullName());
writer.print(")");
}
writer.print(" = ");
if (fieldDescriptor.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
writeMessageValue((Message) value, indent);
} else {
writeValue(fieldDescriptor, value);
}
writer.println(";");
}
static Descriptors.FileDescriptor try_get_inner_deile_desc(String name) {
if (inner_file_descs != null) {
return inner_file_descs.getOrDefault(name.replace('\\', '/').toLowerCase(), null);
}
Descriptors.FileDescriptor[] inner_descs = new Descriptors.FileDescriptor[] { Xresloader.getDescriptor(),
XresloaderUe.getDescriptor(), PbHeaderV3.getDescriptor(), DescriptorProtos.getDescriptor(),
DurationProto.getDescriptor(), TimestampProto.getDescriptor(), AnyProto.getDescriptor(),
ApiProto.getDescriptor(), EmptyProto.getDescriptor(), FieldMaskProto.getDescriptor(),
StructProto.getDescriptor(), TypeProto.getDescriptor(), WrappersProto.getDescriptor(),
SourceContextProto.getDescriptor(), };
inner_file_descs = new HashMap<String, Descriptors.FileDescriptor>();
for (Descriptors.FileDescriptor innerFileDesc : inner_descs) {
inner_file_descs.put(innerFileDesc.getName().replace('\\', '/').toLowerCase(), innerFileDesc);
}
return inner_file_descs.getOrDefault(name.toLowerCase(), null);
}
static private LinkedList<DataVerifyImpl> setup_verifier(Descriptors.Descriptor container,
Descriptors.OneofDescriptor fd) {
LinkedList<DataVerifyImpl> ret = new LinkedList<DataVerifyImpl>();
String rule = String.format("%s.%s.%s", container.getFile().getPackage(), container.getName(), fd.getName());
if (rule.length() > 0 && rule.charAt(0) == '.') {
rule = rule.substring(1);
}
{
DataVerifyImpl vfy = cachePbs.identifiers.getOrDefault(rule, null);
// 命中缓存
if (null != vfy) {
ret.add(vfy);
return ret;
}
}
DataVerifyPbOneof new_vfy = new DataVerifyPbOneof(fd);
cachePbs.identifiers.put(rule, new_vfy);
ret.add(new_vfy);
return ret;
}
private Serde.Schema toSchemaProto(Descriptors.FileDescriptor file) {
Serde.Schema.Builder b = Serde.Schema.newBuilder();
b.setFile(file.toProto());
for (Descriptors.FileDescriptor d : file.getDependencies()) {
b.addImport(toSchemaProto(d));
}
return b.build();
}
private static void handleMapField(
Record record,
Field field,
String fieldPath,
Map<String, Set<Descriptors.FieldDescriptor>> messageTypeToExtensionMap,
Map<String, Object> defaultValueMap,
Descriptors.FieldDescriptor fieldDescriptor,
DynamicMessage.Builder builder
) throws DataGeneratorException {
Descriptors.Descriptor mapEntryDescriptor = fieldDescriptor.getMessageType();
// MapEntry contains key and value fields
Map<String, Field> sdcMapField = field.getValueAsMap();
for (Map.Entry<String, Field> entry : sdcMapField.entrySet()) {
builder.addRepeatedField(fieldDescriptor, DynamicMessage.newBuilder(mapEntryDescriptor)
.setField(mapEntryDescriptor.findFieldByName(KEY), entry.getKey())
.setField(
mapEntryDescriptor.findFieldByName(VALUE),
getValue(
mapEntryDescriptor.findFieldByName(VALUE),
entry.getValue(),
record,
fieldPath + FORWARD_SLASH + entry.getKey(),
messageTypeToExtensionMap,
defaultValueMap
)
)
.build()
);
}
}
private static Map<String, Descriptors.FieldDescriptor> toMap4FieldDescriptor(
Collection<Descriptors.FieldDescriptor> in) {
Map<String, Descriptors.FieldDescriptor> out = new HashMap<>();
in.forEach(
descriptor -> {
out.put(String.valueOf(descriptor.getNumber()), descriptor);
});
return out;
}
private FieldChangeInfo diffField(
Descriptors.FieldDescriptor f_ref, Descriptors.FieldDescriptor f_new) {
diffOptionsFromField(f_ref, f_new);
FieldChangeInfo.Builder builder = FieldChangeInfo.newBuilder();
if (!f_ref.getName().equals(f_new.getName())) {
builder.setChangeType(ChangeType.CHANGED);
builder.setFromName(f_ref.getName());
builder.setToName(f_new.getName());
}
if (!f_ref.getType().equals(f_new.getType())) {
builder.setChangeType(ChangeType.CHANGED);
builder.setFromTypeValue(f_ref.getType().toProto().getNumber());
builder.setToTypeValue(f_new.getType().toProto().getNumber());
if (f_ref.getType().equals(Descriptors.FieldDescriptor.Type.MESSAGE)) {
builder.setFromTypeName(f_ref.getMessageType().getFullName());
}
if (f_new.getType().equals(Descriptors.FieldDescriptor.Type.MESSAGE)) {
builder.setFromTypeName(f_new.getMessageType().getFullName());
}
} else if (f_ref.getType().equals(Descriptors.FieldDescriptor.Type.MESSAGE)
&& !f_ref.getMessageType().getFullName().equals(f_new.getMessageType().getFullName())) {
builder.setChangeType(ChangeType.CHANGED);
builder.setFromTypeName(f_ref.getMessageType().getFullName());
builder.setToTypeName(f_new.getMessageType().getFullName());
}
if (isDeprecated(f_ref) != isDeprecated(f_new)) {
builder.setChangeType(ChangeType.CHANGED);
builder.setFromDeprecated(isDeprecated(f_ref));
builder.setToDeprecated(isDeprecated(f_new));
}
if (builder.getChangeType().equals(ChangeType.CHANGED)) {
return builder.build();
}
return null;
}
protected SyntheticRecordType(@Nonnull RecordMetaData metaData, @Nonnull Descriptors.Descriptor descriptor,
@Nonnull KeyExpression primaryKey, @Nonnull Object recordTypeKey,
@Nonnull List<Index> indexes, @Nonnull List<Index> multiTypeIndexes,
@Nonnull List<C> constituents) {
super(metaData, descriptor, primaryKey, indexes, multiTypeIndexes, null, recordTypeKey);
this.constituents = constituents;
}
private HashMap<String, Integer> getMessageNameToIndexMap(
Descriptors.FileDescriptor fileDescriptor) {
HashMap<String, Integer> indexMap = new HashMap<>();
for (int i = 0; i < fileDescriptor.getMessageTypes().size(); i++) {
Descriptors.Descriptor descriptor = fileDescriptor.getMessageTypes().get(i);
indexMap.put(descriptor.getFullName(), i);
}
return indexMap;
}
private Report lintMessage(Descriptors.Descriptor d) throws IOException {
ProtoDomain pd = ProtoDomain.buildFrom(d);
String message = d.getFullName();
ValidationResults results = new ValidationResults();
ProtoLint lint = new ProtoLint(pd, results);
lint.lintOnMessage(message);
return results.createProto();
}
private void updateRecordType(@Nonnull Map<String, RecordTypeBuilder> oldRecordTypes,
@Nonnull Descriptors.Descriptor oldDescriptor,
@Nonnull Descriptors.Descriptor newDescriptor) {
// Create a new record type based off the old one
RecordTypeBuilder oldRecordType = oldRecordTypes.get(oldDescriptor.getName());
RecordTypeBuilder newRecordType = new RecordTypeBuilder(newDescriptor, oldRecordType);
recordTypes.put(newRecordType.getName(), newRecordType); // update the record type builder
}
public void lintOnService(Descriptors.ServiceDescriptor service) {
String name = service.getName();
if (!isPascalCase(name)) {
results.addResult(
service,
RuleInfo.newBuilder()
.setLintRule(LintRule.LINT_SERVICE_NAME_SHOULD_BE_PASCAL)
.setCode(String.format("L%d/00", LintRule.LINT_SERVICE_NAME_SHOULD_BE_PASCAL_VALUE))
.build());
}
service.getMethods().forEach(m -> lintMethod(m));
}
/**
* 解析字段属性
* 字段分为 primitive integer(int32, int64), float, double, string,
* object类型 array类型
* object类型指向 lookupTable里的字段, 并使用$ref表示引用
* array类型,type是array,具体item是字段类型
*/
public void processMessageFields() {
typeLookupTable.forEach((typeName, definitionType) -> {
Descriptor protocolDescriptor = definitionType.getProtocolDescriptor();
Map<String, FieldProperty> properties = definitionType.getProperties();
List<Descriptors.FieldDescriptor> fields = protocolDescriptor.getFields();
fields.forEach(fieldDescriptor -> {
FieldProperty fieldProperty = parseFieldProperty(fieldDescriptor);
properties.put(fieldDescriptor.getName(), fieldProperty);
});
});
}
@Nonnull
private FDBMetaDataStore createMetaDataStore(@Nonnull FDBRecordContext context, @Nonnull KeySpacePath metaDataPath,
@Nonnull Subspace metaDataSubspace,
@Nullable Descriptors.FileDescriptor localFileDescriptor) {
FDBMetaDataStore metaDataStore = new FDBMetaDataStore(context, metaDataPath);
metaDataStore.setMaintainHistory(false);
assertEquals(metaDataSubspace, metaDataStore.getSubspace());
metaDataStore.setDependencies(new Descriptors.FileDescriptor[]{RecordMetaDataOptionsProto.getDescriptor()});
metaDataStore.setLocalFileDescriptor(localFileDescriptor);
return metaDataStore;
}
/**
* Fills lookup structure for translating between parquet enum values and Protocol buffer enum values.
* */
private Map<Binary, Descriptors.EnumValueDescriptor> makeLookupStructure(Descriptors.FieldDescriptor enumFieldType) {
Descriptors.EnumDescriptor enumType = enumFieldType.getEnumType();
Map<Binary, Descriptors.EnumValueDescriptor> lookupStructure = new HashMap<Binary, Descriptors.EnumValueDescriptor>();
List<Descriptors.EnumValueDescriptor> enumValues = enumType.getValues();
for (Descriptors.EnumValueDescriptor value : enumValues) {
String name = value.getName();
lookupStructure.put(Binary.fromString(name), enumType.findValueByName(name));
}
return lookupStructure;
}