1 package com.google.protobuf.jruby; 2 3 import com.google.protobuf.DescriptorProtos; 4 import com.google.protobuf.Descriptors; 5 import org.jruby.Ruby; 6 import org.jruby.RubyClass; 7 import org.jruby.RubyModule; 8 import org.jruby.RubyObject; 9 import org.jruby.anno.JRubyClass; 10 import org.jruby.anno.JRubyMethod; 11 import org.jruby.runtime.Block; 12 import org.jruby.runtime.ObjectAllocator; 13 import org.jruby.runtime.ThreadContext; 14 import org.jruby.runtime.builtin.IRubyObject; 15 16 import java.util.*; 17 18 @JRubyClass(name = "OneofDescriptor", include = "Enumerable") 19 public class RubyOneofDescriptor extends RubyObject { 20 createRubyOneofDescriptor(Ruby runtime)21 public static void createRubyOneofDescriptor(Ruby runtime) { 22 RubyModule protobuf = runtime.getClassFromPath("Google::Protobuf"); 23 RubyClass cRubyOneofDescriptor = protobuf.defineClassUnder("OneofDescriptor", runtime.getObject(), new ObjectAllocator() { 24 @Override 25 public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) { 26 return new RubyOneofDescriptor(ruby, rubyClass); 27 } 28 }); 29 cRubyOneofDescriptor.defineAnnotatedMethods(RubyOneofDescriptor.class); 30 cRubyOneofDescriptor.includeModule(runtime.getEnumerable()); 31 } 32 RubyOneofDescriptor(Ruby ruby, RubyClass rubyClass)33 public RubyOneofDescriptor(Ruby ruby, RubyClass rubyClass) { 34 super(ruby, rubyClass); 35 } 36 37 @JRubyMethod initialize(ThreadContext context)38 public IRubyObject initialize(ThreadContext context) { 39 builder = DescriptorProtos.OneofDescriptorProto.newBuilder(); 40 fields = new ArrayList<RubyFieldDescriptor>(); 41 return this; 42 } 43 44 /* 45 * call-seq: 46 * OneofDescriptor.name => name 47 * 48 * Returns the name of this oneof. 49 */ 50 @JRubyMethod(name = "name") getName(ThreadContext context)51 public IRubyObject getName(ThreadContext context) { 52 return name; 53 } 54 55 /* 56 * call-seq: 57 * OneofDescriptor.name = name 58 * 59 * Sets a new name for this oneof. The oneof must not have been added to a 60 * message descriptor yet. 61 */ 62 @JRubyMethod(name = "name=") setName(ThreadContext context, IRubyObject name)63 public IRubyObject setName(ThreadContext context, IRubyObject name) { 64 this.name = context.runtime.newString(name.asJavaString()); 65 this.builder.setName(name.asJavaString()); 66 return context.runtime.getNil(); 67 } 68 69 /* 70 * call-seq: 71 * OneofDescriptor.add_field(field) => nil 72 * 73 * Adds a field to this oneof. The field may have been added to this oneof in 74 * the past, or the message to which this oneof belongs (if any), but may not 75 * have already been added to any other oneof or message. Otherwise, an 76 * exception is raised. 77 * 78 * All fields added to the oneof via this method will be automatically added to 79 * the message to which this oneof belongs, if it belongs to one currently, or 80 * else will be added to any message to which the oneof is later added at the 81 * time that it is added. 82 */ 83 @JRubyMethod(name = "add_field") addField(ThreadContext context, IRubyObject obj)84 public IRubyObject addField(ThreadContext context, IRubyObject obj) { 85 RubyFieldDescriptor fieldDescriptor = (RubyFieldDescriptor) obj; 86 fieldDescriptor.setOneofName(this.name); 87 fields.add(fieldDescriptor); 88 return context.runtime.getNil(); 89 } 90 91 /* 92 * call-seq: 93 * OneofDescriptor.each(&block) => nil 94 * 95 * Iterates through fields in this oneof, yielding to the block on each one. 96 */ 97 @JRubyMethod each(ThreadContext context, Block block)98 public IRubyObject each(ThreadContext context, Block block) { 99 for (RubyFieldDescriptor field : fields) { 100 block.yieldSpecific(context, field); 101 } 102 return context.runtime.getNil(); 103 } 104 build(int index)105 public DescriptorProtos.OneofDescriptorProto build(int index) { 106 for (RubyFieldDescriptor field: fields) { 107 field.setOneofIndex(index); 108 } 109 return this.builder.build(); 110 } 111 getFields()112 protected Collection<RubyFieldDescriptor> getFields() { 113 return fields; 114 } 115 getOneofDescriptor()116 protected Descriptors.OneofDescriptor getOneofDescriptor() { 117 RubyFieldDescriptor fieldDescriptor = fields.get(0); 118 return fieldDescriptor.getFieldDef().getContainingOneof(); 119 } 120 121 private IRubyObject name; 122 private DescriptorProtos.OneofDescriptorProto.Builder builder; 123 private List<RubyFieldDescriptor> fields; 124 } 125