aboutsummaryrefslogtreecommitdiffhomepage
path: root/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java
blob: cc4ab662846c489b06b88d23ac8868c7d674cc2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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;
}