下面列出了怎么用com.google.protobuf.Descriptors.Descriptor的API类实例代码及写法,或者点击链接到github查看源代码。
/** Internal helper which returns a mutable map. */
private Map<FieldDescriptor, Object> getAllFieldsMutable() {
final TreeMap<FieldDescriptor, Object> result =
new TreeMap<FieldDescriptor, Object>();
final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
for (final FieldDescriptor field : descriptor.getFields()) {
if (field.isRepeated()) {
final List value = (List) getField(field);
if (!value.isEmpty()) {
result.put(field, value);
}
} else {
if (hasField(field)) {
result.put(field, getField(field));
}
}
}
return result;
}
/** Internal helper which returns a mutable map. */
private Map<FieldDescriptor, Object> getAllFieldsMutable() {
final TreeMap<FieldDescriptor, Object> result =
new TreeMap<FieldDescriptor, Object>();
final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
for (final FieldDescriptor field : descriptor.getFields()) {
if (field.isRepeated()) {
final List<?> value = (List<?>) getField(field);
if (!value.isEmpty()) {
result.put(field, value);
}
} else {
if (hasField(field)) {
result.put(field, getField(field));
}
}
}
return result;
}
private ExtensionRegistryWrapper(final ExtensionRegistry extensionRegistry) {
this.extensionFunction = new Function<Descriptor, Set<ExtensionInfo>>() {
private final Map<Descriptor, Set<ExtensionInfo>> extensionCache = new ConcurrentHashMap<>();
@Override
public Set<ExtensionInfo> apply(Descriptor descriptor) {
Set<ExtensionInfo> cached = extensionCache.get(descriptor);
if (cached != null) {
return cached;
}
Set<ExtensionInfo> extensions =
extensionRegistry.getAllImmutableExtensionsByExtendedType(descriptor.getFullName());
extensionCache.put(descriptor, extensions);
return extensions;
}
};
}
/** Internal helper which returns a mutable map. */
private Map<FieldDescriptor, Object> getAllFieldsMutable() {
final TreeMap<FieldDescriptor, Object> result =
new TreeMap<FieldDescriptor, Object>();
final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
for (final FieldDescriptor field : descriptor.getFields()) {
if (field.isRepeated()) {
final List value = (List) getField(field);
if (!value.isEmpty()) {
result.put(field, value);
}
} else {
if (hasField(field)) {
result.put(field, getField(field));
}
}
}
return result;
}
protected RuleBasedConfigAspect(
Model model,
Key<AttributeType> key,
String aspectName,
Descriptor ruleDescriptor,
List<RuleType> rules,
boolean alwaysEvaluate) {
super(model, aspectName);
this.alwaysEvaluate = alwaysEvaluate;
this.key = key;
this.rules =
new ConfigRuleSet<>(
ruleDescriptor,
rules,
model.getExperiments(),
model.getLocationResolver(),
model.getDiagReporter());
this.rules.reportBadSelectors(getAspectName());
}
@BeforeClass
public static void setup() {
allFields = new HashSet<>();
arrayFields = new HashSet<>();
Descriptor descriptor = AllFields.getDescriptor();
for (FieldDescriptor field : descriptor.getFields()) {
allFields.add(translate(field.getName()));
if (field.isRepeated()) {
arrayFields.add(translate(field.getName()));
}
}
allExtensionFields = new HashSet<>();
arrayExtensionFields = new HashSet<>();
ExtensionRegistryWrapper extensionRegistry = ExtensionRegistryWrapper.wrap(EXTENSION_REGISTRY);
for (ExtensionInfo extensionInfo : extensionRegistry.getExtensionsByDescriptor(descriptor)) {
allExtensionFields.add(translate(extensionInfo.descriptor.getName()));
if (extensionInfo.descriptor.isRepeated()) {
arrayExtensionFields.add(translate(extensionInfo.descriptor.getName()));
}
}
}
public void testReflection() throws Exception {
Descriptor descriptor = OneofMsg.getDescriptor();
FieldDescriptor stringField = descriptor.findFieldByNumber(6);
FieldDescriptor intField = descriptor.findFieldByNumber(4);
FieldDescriptor messageField = descriptor.findFieldByNumber(1);
OneofMsg msg = getFilledMessage(OneofGroupCase.ONEOF_STRING);
assertEquals("goodbye", msg.getField(stringField));
assertFalse(msg.hasField(intField));
assertFalse(msg.hasField(messageField));
OneofMsg.Builder builder = msg.toBuilder();
builder.setField(messageField, OneofFoo.newBuilder().setFoo("baz").build());
assertEquals("baz", builder.getOneofMessage().getFoo());
assertFalse(builder.hasOneofString());
assertFalse(builder.hasOneofInt());
}
/**
* generate <code>getDescriptor</code> method code
*
* @return source code
*/
private Object getGetDescriptorMethodCode() {
StringBuilder code = new StringBuilder();
String descriptorClsName = ClassHelper.getInternalName(Descriptor.class.getCanonicalName());
code.append("public ").append(descriptorClsName);
code.append(" getDescriptor() throws IOException {").append(LINE_BREAK);
code.append("if (this.descriptor != null) {").append(LINE_BREAK);
code.append("return this.descriptor").append(JAVA_LINE_BREAK);
code.append("}").append(LINE_BREAK);
code.append(descriptorClsName).append(" descriptor = ");
code.append("CodedConstant.getDescriptor(").append(ClassHelper.getInternalName(cls.getCanonicalName()))
.append(JAVA_CLASS_FILE_SUFFIX).append(")").append(JAVA_LINE_BREAK);
code.append("return (this.descriptor = descriptor)").append(JAVA_LINE_BREAK);
code.append("}").append(LINE_BREAK);
return code.toString();
}
/**
* Encodes the data portion of an ExecutionResult as ByteString.
*
* <p>The FileDescriptorSet must contain a message with the name "{operationName}Response". This
* message will be populated with data from the execution result and encoded as a ByteString.
*/
public static ByteString encodeResponse(
String operationName, FileDescriptorSet fileDescriptorSet, ExecutionResult executionResult) {
try {
// TODO: Support multiple FileDescriptors in FileDescriptorSet
FileDescriptor fileDescriptor =
FileDescriptor.buildFrom(fileDescriptorSet.getFileList().get(0), new FileDescriptor[] {});
Descriptor messageType = fileDescriptor.findMessageTypeByName(operationName + "Response");
Message message = DynamicMessage.parseFrom(messageType, ByteString.EMPTY);
Message responseData = QueryResponseToProto.buildMessage(message, executionResult.getData());
return responseData.toByteString();
} catch (DescriptorValidationException | InvalidProtocolBufferException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
protected void writeMap(
FieldDescriptor field,
Object entries,
JsonGenerator generator,
SerializerProvider serializerProvider
) throws IOException {
Descriptor entryDescriptor = field.getMessageType();
FieldDescriptor keyDescriptor = entryDescriptor.findFieldByName("key");
FieldDescriptor valueDescriptor = entryDescriptor.findFieldByName("value");
generator.writeStartObject();
for (Message entry : (List<? extends Message>) entries) {
// map keys can only be integers or strings so this should be fine
generator.writeFieldName(entry.getField(keyDescriptor).toString());
Object value = entry.getField(valueDescriptor);
// map values can't be maps or repeated so this should be fine
writeValue(valueDescriptor, value, generator, serializerProvider);
}
generator.writeEndObject();
}
private Object getValueForField(FieldDescriptor field, Object value, Message.Builder builder) {
// TODO: handle groups, oneof
if (field.getType() == FieldDescriptor.Type.MESSAGE) {
Descriptor fieldTypeDescriptor =
descriptorMapping.get(getReferenceName(field.getMessageType()));
return createProtoBuf(
fieldTypeDescriptor, builder.newBuilderForField(field), (Map<String, Object>) value);
}
if (field.getType() == FieldDescriptor.Type.ENUM) {
EnumDescriptor enumDescriptor =
enumMapping.get(ProtoToGql.getReferenceName(field.getEnumType()));
return enumDescriptor.findValueByName(value.toString());
}
if (field.getType() == FieldDescriptor.Type.FLOAT) {
if (value instanceof Double) {
return ((Double) value).floatValue();
}
}
return value;
}
private DefinitionType buildDefinitionType(Descriptor descriptor) {
DefinitionType definitionType = new DefinitionType();
definitionType.setTitle(descriptor.getName());
definitionType.setType(FieldTypeEnum.OBJECT.getType());
definitionType.setProperties(new HashMap<>());
definitionType.setProtocolDescriptor(descriptor);
return definitionType;
}
/**
* 解析字段属性
* 字段分为 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);
});
});
}
@VisibleForTesting
StructInfo newStructInfo(Descriptor descriptor) {
return new StructInfo(
descriptor.getFullName(),
descriptor.getFields().stream()
.map(GrpcDocServicePlugin::newFieldInfo)
.collect(toImmutableList()));
}
/**
* Construct a FieldAccessorTable for a particular message class without
* initializing FieldAccessors.
*/
public FieldAccessorTable(
final Descriptor descriptor,
final String[] camelCaseNames) {
this.descriptor = descriptor;
this.camelCaseNames = camelCaseNames;
fields = new FieldAccessor[descriptor.getFields().size()];
initialized = false;
}
/**
* Instantiates a new metadata.
*
* @param descriptor the descriptor
* @param defaultInstance the default instance
* @param keyType the key type
* @param valueType the value type
*/
public Metadata(Descriptor descriptor, MapEntry<K, V> defaultInstance, WireFormat.FieldType keyType,
WireFormat.FieldType valueType) {
super(keyType, defaultInstance.key, valueType, defaultInstance.value);
this.descriptor = descriptor;
this.parser = new AbstractParser<MapEntry<K, V>>() {
@Override
public MapEntry<K, V> parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return new MapEntry<K, V>(Metadata.this, input, extensionRegistry);
}
};
}
@Override
final void writeRawValue(Object value) {
Collection<Message> collection = (Collection<Message>) value;
if (collection.isEmpty()) {
return;
}
recordConsumer.startField(fieldName, index);
recordConsumer.startGroup();
recordConsumer.startField("key_value", 0); // This is the wrapper group for the map field
for (Message msg : collection) {
recordConsumer.startGroup();
final Descriptor descriptorForType = msg.getDescriptorForType();
final FieldDescriptor keyDesc = descriptorForType.findFieldByName("key");
final FieldDescriptor valueDesc = descriptorForType.findFieldByName("value");
keyWriter.writeField(msg.getField(keyDesc));
valueWriter.writeField(msg.getField(valueDesc));
recordConsumer.endGroup();
}
recordConsumer.endField("key_value", 0);
recordConsumer.endGroup();
recordConsumer.endField(fieldName, index);
}
private static <M extends Message> ProtobufSerializerSnapshot createSnapshot(Class<M> type) {
Descriptor messageDescriptor = ProtobufReflectionUtil.protobufDescriptor(type);
FileDescriptorSet dependencies =
ProtobufReflectionUtil.protoFileDescriptorSet(messageDescriptor);
return ProtobufSerializerSnapshot.newBuilder()
.setMessageName(messageDescriptor.getFullName())
.setGeneratedJavaName(type.getName())
.setDescriptorSet(dependencies)
.build();
}
/** Parse a message of the given type from the given input stream. */
public static DynamicMessage parseFrom(
Descriptor type,
CodedInputStream input,
ExtensionRegistry extensionRegistry)
throws IOException {
return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
}
protected RuleBasedConfigAspect(
Model model,
Key<AttributeType> key,
String aspectName,
Descriptor ruleDescriptor,
List<RuleType> rules) {
this(model, key, aspectName, ruleDescriptor, rules, false);
}
/**
* Get a {@code DynamicMessage} representing the default instance of the
* given type.
*/
public static DynamicMessage getDefaultInstance(Descriptor type) {
int oneofDeclCount = type.toProto().getOneofDeclCount();
FieldDescriptor[] oneofCases = new FieldDescriptor[oneofDeclCount];
return new DynamicMessage(type, FieldSet.<FieldDescriptor>emptySet(),
oneofCases,
UnknownFieldSet.getDefaultInstance());
}
/** Parse a message of the given type from the given input stream. */
public static DynamicMessage parseFrom(
Descriptor type,
CodedInputStream input,
ExtensionRegistry extensionRegistry)
throws IOException {
return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
}
static FileDescriptorSet protoFileDescriptorSet(Descriptor descriptor) {
Set<FileDescriptor> descriptors = new HashSet<>();
descriptors.add(descriptor.getFile());
addDependenciesRecursively(descriptors, descriptor.getFile());
Builder fileDescriptorSet = FileDescriptorSet.newBuilder();
for (FileDescriptor d : descriptors) {
fileDescriptorSet.addFile(d.toProto());
}
return fileDescriptorSet.build();
}
/** extract the {@linkplain Descriptor} for the generated message type. */
static <M extends Message> Descriptor protobufDescriptor(Class<M> type) {
try {
Method getDescriptor = type.getDeclaredMethod("getDescriptor");
return (Descriptor) getDescriptor.invoke(type);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException(
"unable to obtain protobuf type fileDescriptorSet for " + type, e);
}
}
/**
* @return the nested messages of the message
*/
public List<Message> getNestedMessages() {
if (messages == null) {
ImmutableList.Builder<Message> builder = ImmutableList.builder();
for (Descriptor d : descriptor.getNestedTypes()) {
builder.add(adapt(d));
}
messages = builder.build();
}
return messages;
}
/**
* @return the nested messages of the message
*/
public List<Message> getNestedMessages() {
if (messages == null) {
ImmutableList.Builder<Message> builder = ImmutableList.builder();
for (Descriptor d : descriptor.getNestedTypes()) {
builder.add(adapt(d));
}
messages = builder.build();
}
return messages;
}
/**
* testBasic - basic usage
*/
@Test
public void testBasic() throws Exception {
log("--- testBasic ---");
// Create dynamic schema
DynamicSchema.Builder schemaBuilder = DynamicSchema.newBuilder();
schemaBuilder.setName("PersonSchemaDynamic.proto");
MessageDefinition msgDef = MessageDefinition.newBuilder("Person") // message Person
.addField("required", "int32", "id", 1) // required int32 id = 1
.addField("required", "string", "name", 2) // required string name = 2
.addField("optional", "string", "email", 3) // optional string email = 3
.build();
schemaBuilder.addMessageDefinition(msgDef);
DynamicSchema schema = schemaBuilder.build();
log(schema);
// Create dynamic message from schema
DynamicMessage.Builder msgBuilder = schema.newMessageBuilder("Person");
Descriptor msgDesc = msgBuilder.getDescriptorForType();
DynamicMessage msg = msgBuilder
.setField(msgDesc.findFieldByName("id"), 1)
.setField(msgDesc.findFieldByName("name"), "Alan Turing")
.setField(msgDesc.findFieldByName("email"), "[email protected]")
.build();
log(msg);
// Create data object traditional way using generated code
PersonSchema.Person person = PersonSchema.Person.newBuilder()
.setId(1)
.setName("Alan Turing")
.setEmail("[email protected]")
.build();
// Should be equivalent
Assert.assertEquals(person.toString(), msg.toString());
}
@Override
public final void validate(
Descriptor rootDescriptor, FieldDescriptorValidator fieldDescriptorValidator) {
for (FieldScopeLogic elem : elements) {
elem.validate(rootDescriptor, fieldDescriptorValidator);
}
}
private void parseNestModelType(List<Descriptor> descriptors) {
if (CollectionUtils.isEmpty(descriptors)) {
return;
}
descriptors.forEach(d -> {
boolean isMap = ofNullable(d.getOptions()).map(MessageOptions::getMapEntry).orElse(false);
if (isMap) {
return;
}
typeLookupTable.put(d.getFullName(), buildDefinitionType(d));
});
}
private DefinitionType buildDefinitionType(Descriptor descriptor) {
DefinitionType definitionType = new DefinitionType();
definitionType.setTitle(descriptor.getName());
definitionType.setType(FieldTypeEnum.OBJECT.getType());
definitionType.setProperties(new HashMap<>());
definitionType.setProtocolDescriptor(descriptor);
return definitionType;
}