blob: cc4ab662846c489b06b88d23ac8868c7d674cc2a [file] [log] [blame]
package com.google.protobuf.jruby;
import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import java.util.*;
@JRubyClass(name = "OneofDescriptor", include = "Enumerable")
public class RubyOneofDescriptor extends RubyObject {
public static void createRubyOneofDescriptor(Ruby runtime) {
RubyModule protobuf = runtime.getClassFromPath("Google::Protobuf");
RubyClass cRubyOneofDescriptor = protobuf.defineClassUnder("OneofDescriptor", runtime.getObject(), new ObjectAllocator() {
@Override
public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
return new RubyOneofDescriptor(ruby, rubyClass);
}
});
cRubyOneofDescriptor.defineAnnotatedMethods(RubyOneofDescriptor.class);
cRubyOneofDescriptor.includeModule(runtime.getEnumerable());
}
public RubyOneofDescriptor(Ruby ruby, RubyClass rubyClass) {
super(ruby, rubyClass);
}
@JRubyMethod
public IRubyObject initialize(ThreadContext context) {
builder = DescriptorProtos.OneofDescriptorProto.newBuilder();
fields = new ArrayList<RubyFieldDescriptor>();
return this;
}
/*
* call-seq:
* OneofDescriptor.name => name
*
* Returns the name of this oneof.
*/
@JRubyMethod(name = "name")
public IRubyObject getName(ThreadContext context) {
return name;
}
/*
* call-seq:
* OneofDescriptor.name = name
*
* Sets a new name for this oneof. The oneof must not have been added to a
* message descriptor yet.
*/
@JRubyMethod(name = "name=")
public IRubyObject setName(ThreadContext context, IRubyObject name) {
this.name = context.runtime.newString(name.asJavaString());
this.builder.setName(name.asJavaString());
return context.runtime.getNil();
}
/*
* call-seq:
* OneofDescriptor.add_field(field) => nil
*
* Adds a field to this oneof. The field may have been added to this oneof in
* the past, or the message to which this oneof belongs (if any), but may not
* have already been added to any other oneof or message. Otherwise, an
* exception is raised.
*
* All fields added to the oneof via this method will be automatically added to
* the message to which this oneof belongs, if it belongs to one currently, or
* else will be added to any message to which the oneof is later added at the
* time that it is added.
*/
@JRubyMethod(name = "add_field")
public IRubyObject addField(ThreadContext context, IRubyObject obj) {
RubyFieldDescriptor fieldDescriptor = (RubyFieldDescriptor) obj;
fieldDescriptor.setOneofName(this.name);
fields.add(fieldDescriptor);
return context.runtime.getNil();
}
/*
* call-seq:
* OneofDescriptor.each(&block) => nil
*
* Iterates through fields in this oneof, yielding to the block on each one.
*/
@JRubyMethod
public IRubyObject each(ThreadContext context, Block block) {
for (RubyFieldDescriptor field : fields) {
block.yieldSpecific(context, field);
}
return context.runtime.getNil();
}
public DescriptorProtos.OneofDescriptorProto build(int index) {
for (RubyFieldDescriptor field: fields) {
field.setOneofIndex(index);
}
return this.builder.build();
}
protected Collection<RubyFieldDescriptor> getFields() {
return fields;
}
protected Descriptors.OneofDescriptor getOneofDescriptor() {
RubyFieldDescriptor fieldDescriptor = fields.get(0);
return fieldDescriptor.getFieldDef().getContainingOneof();
}
private IRubyObject name;
private DescriptorProtos.OneofDescriptorProto.Builder builder;
private List<RubyFieldDescriptor> fields;
}