content: 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;
  }
  