|
|
|
@ -36,7 +36,9 @@ import com.google.protobuf.DescriptorProtos.FileDescriptorProto; |
|
|
|
|
import com.google.protobuf.Descriptors.Descriptor; |
|
|
|
|
import com.google.protobuf.Descriptors.DescriptorValidationException; |
|
|
|
|
import com.google.protobuf.Descriptors.EnumDescriptor; |
|
|
|
|
import com.google.protobuf.Descriptors.FieldDescriptor; |
|
|
|
|
import com.google.protobuf.Descriptors.FileDescriptor; |
|
|
|
|
import com.google.protobuf.ExtensionRegistry; |
|
|
|
|
import com.google.protobuf.InvalidProtocolBufferException; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.HashMap; |
|
|
|
@ -70,6 +72,7 @@ public class RubyDescriptorPool extends RubyObject { |
|
|
|
|
cDescriptorPool.newInstance(runtime.getCurrentContext(), Block.NULL_BLOCK); |
|
|
|
|
cDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Descriptor"); |
|
|
|
|
cEnumDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::EnumDescriptor"); |
|
|
|
|
cFieldDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::FieldDescriptor"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public RubyDescriptorPool(Ruby runtime, RubyClass klazz) { |
|
|
|
@ -92,7 +95,7 @@ public class RubyDescriptorPool extends RubyObject { |
|
|
|
|
* call-seq: |
|
|
|
|
* DescriptorPool.lookup(name) => descriptor |
|
|
|
|
* |
|
|
|
|
* Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none |
|
|
|
|
* Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it, or nil if none |
|
|
|
|
* exists with the given name. |
|
|
|
|
* |
|
|
|
|
* This currently lazy loads the ruby descriptor objects as they are requested. |
|
|
|
@ -121,7 +124,8 @@ public class RubyDescriptorPool extends RubyObject { |
|
|
|
|
public IRubyObject add_serialized_file(ThreadContext context, IRubyObject data) { |
|
|
|
|
byte[] bin = data.convertToString().getBytes(); |
|
|
|
|
try { |
|
|
|
|
FileDescriptorProto.Builder builder = FileDescriptorProto.newBuilder().mergeFrom(bin); |
|
|
|
|
FileDescriptorProto.Builder builder = |
|
|
|
|
FileDescriptorProto.newBuilder().mergeFrom(bin, registry); |
|
|
|
|
registerFileDescriptor(context, builder); |
|
|
|
|
} catch (InvalidProtocolBufferException e) { |
|
|
|
|
throw RaiseException.from( |
|
|
|
@ -150,6 +154,8 @@ public class RubyDescriptorPool extends RubyObject { |
|
|
|
|
for (EnumDescriptor ed : fd.getEnumTypes()) registerEnumDescriptor(context, ed, packageName); |
|
|
|
|
for (Descriptor message : fd.getMessageTypes()) |
|
|
|
|
registerDescriptor(context, message, packageName); |
|
|
|
|
for (FieldDescriptor fieldDescriptor : fd.getExtensions()) |
|
|
|
|
registerExtension(context, fieldDescriptor, packageName); |
|
|
|
|
|
|
|
|
|
// Mark this as a loaded file
|
|
|
|
|
fileDescriptors.add(fd); |
|
|
|
@ -170,6 +176,24 @@ public class RubyDescriptorPool extends RubyObject { |
|
|
|
|
registerEnumDescriptor(context, ed, fullPath); |
|
|
|
|
for (Descriptor message : descriptor.getNestedTypes()) |
|
|
|
|
registerDescriptor(context, message, fullPath); |
|
|
|
|
for (FieldDescriptor fieldDescriptor : descriptor.getExtensions()) |
|
|
|
|
registerExtension(context, fieldDescriptor, fullPath); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void registerExtension( |
|
|
|
|
ThreadContext context, FieldDescriptor descriptor, String parentPath) { |
|
|
|
|
if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { |
|
|
|
|
registry.add(descriptor, descriptor.toProto()); |
|
|
|
|
} else { |
|
|
|
|
registry.add(descriptor); |
|
|
|
|
} |
|
|
|
|
RubyString name = context.runtime.newString(parentPath + descriptor.getName()); |
|
|
|
|
RubyFieldDescriptor des = |
|
|
|
|
(RubyFieldDescriptor) cFieldDescriptor.newInstance(context, Block.NULL_BLOCK); |
|
|
|
|
des.setName(name); |
|
|
|
|
des.setDescriptor(context, descriptor, this); |
|
|
|
|
// For MessageSet extensions, there is the possibility of a name conflict. Prefer the Message.
|
|
|
|
|
symtab.putIfAbsent(name, des); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void registerEnumDescriptor( |
|
|
|
@ -188,8 +212,10 @@ public class RubyDescriptorPool extends RubyObject { |
|
|
|
|
|
|
|
|
|
private static RubyClass cDescriptor; |
|
|
|
|
private static RubyClass cEnumDescriptor; |
|
|
|
|
private static RubyClass cFieldDescriptor; |
|
|
|
|
private static RubyDescriptorPool descriptorPool; |
|
|
|
|
|
|
|
|
|
private List<FileDescriptor> fileDescriptors; |
|
|
|
|
private Map<IRubyObject, IRubyObject> symtab; |
|
|
|
|
protected static final ExtensionRegistry registry = ExtensionRegistry.newInstance(); |
|
|
|
|
} |
|
|
|
|