RubyDescriptor.java
Go to the documentation of this file.
1 /*
2  * Protocol Buffers - Google's data interchange format
3  * Copyright 2014 Google Inc. All rights reserved.
4  * https://developers.google.com/protocol-buffers/
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of Google Inc. nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package com.google.protobuf.jruby;
34 
37 import org.jruby.*;
38 import org.jruby.anno.JRubyClass;
39 import org.jruby.anno.JRubyMethod;
40 import org.jruby.runtime.Block;
41 import org.jruby.runtime.ObjectAllocator;
42 import org.jruby.runtime.ThreadContext;
43 import org.jruby.runtime.builtin.IRubyObject;
44 
45 import java.util.HashMap;
46 import java.util.Map;
47 
48 
49 @JRubyClass(name = "Descriptor", include = "Enumerable")
50 public class RubyDescriptor extends RubyObject {
51  public static void createRubyDescriptor(Ruby runtime) {
52  RubyModule protobuf = runtime.getClassFromPath("Google::Protobuf");
53  RubyClass cDescriptor = protobuf.defineClassUnder("Descriptor", runtime.getObject(), new ObjectAllocator() {
54  @Override
55  public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
56  return new RubyDescriptor(runtime, klazz);
57  }
58  });
59  cDescriptor.includeModule(runtime.getEnumerable());
60  cDescriptor.defineAnnotatedMethods(RubyDescriptor.class);
61  }
62 
63  public RubyDescriptor(Ruby runtime, RubyClass klazz) {
64  super(runtime, klazz);
65  }
66 
67  /*
68  * call-seq:
69  * Descriptor.new => descriptor
70  *
71  * Creates a new, empty, message type descriptor. At a minimum, its name must be
72  * set before it is added to a pool. It cannot be used to create messages until
73  * it is added to a pool, after which it becomes immutable (as part of a
74  * finalization process).
75  */
76  @JRubyMethod
77  public IRubyObject initialize(ThreadContext context) {
78  this.builder = DescriptorProtos.DescriptorProto.newBuilder();
79  this.fieldDefMap = new HashMap<String, RubyFieldDescriptor>();
80  this.oneofDefs = new HashMap<IRubyObject, RubyOneofDescriptor>();
81  return this;
82  }
83 
84  /*
85  * call-seq:
86  * Descriptor.name => name
87  *
88  * Returns the name of this message type as a fully-qualfied string (e.g.,
89  * My.Package.MessageType).
90  */
91  @JRubyMethod(name = "name")
92  public IRubyObject getName(ThreadContext context) {
93  return this.name;
94  }
95 
96  /*
97  * call-seq:
98  * Descriptor.name = name
99  *
100  * Assigns a name to this message type. The descriptor must not have been added
101  * to a pool yet.
102  */
103  @JRubyMethod(name = "name=")
104  public IRubyObject setName(ThreadContext context, IRubyObject name) {
105  this.name = name;
106  this.builder.setName(Utils.escapeIdentifier(this.name.asJavaString()));
107  return context.runtime.getNil();
108  }
109 
110  /*
111  * call-seq:
112  * Descriptor.add_field(field) => nil
113  *
114  * Adds the given FieldDescriptor to this message type. The descriptor must not
115  * have been added to a pool yet. Raises an exception if a field with the same
116  * name or number already exists. Sub-type references (e.g. for fields of type
117  * message) are not resolved at this point.
118  */
119  @JRubyMethod(name = "add_field")
120  public IRubyObject addField(ThreadContext context, IRubyObject obj) {
122  this.fieldDefMap.put(fieldDef.getName(context).asJavaString(), fieldDef);
123  this.builder.addField(fieldDef.build());
124  return context.runtime.getNil();
125  }
126 
127  /*
128  * call-seq:
129  * Descriptor.lookup(name) => FieldDescriptor
130  *
131  * Returns the field descriptor for the field with the given name, if present,
132  * or nil if none.
133  */
134  @JRubyMethod
135  public IRubyObject lookup(ThreadContext context, IRubyObject fieldName) {
136  return this.fieldDefMap.get(fieldName.asJavaString());
137  }
138 
139  /*
140  * call-seq:
141  * Descriptor.msgclass => message_klass
142  *
143  * Returns the Ruby class created for this message type. Valid only once the
144  * message type has been added to a pool.
145  */
146  @JRubyMethod
147  public IRubyObject msgclass(ThreadContext context) {
148  if (this.klazz == null) {
149  this.klazz = buildClassFromDescriptor(context);
150  }
151  return this.klazz;
152  }
153 
154  /*
155  * call-seq:
156  * Descriptor.each(&block)
157  *
158  * Iterates over fields in this message type, yielding to the block on each one.
159  */
160  @JRubyMethod
161  public IRubyObject each(ThreadContext context, Block block) {
162  for (Map.Entry<String, RubyFieldDescriptor> entry : fieldDefMap.entrySet()) {
163  block.yield(context, entry.getValue());
164  }
165  return context.runtime.getNil();
166  }
167 
168  /*
169  * call-seq:
170  * Descriptor.add_oneof(oneof) => nil
171  *
172  * Adds the given OneofDescriptor to this message type. This descriptor must not
173  * have been added to a pool yet. Raises an exception if a oneof with the same
174  * name already exists, or if any of the oneof's fields' names or numbers
175  * conflict with an existing field in this message type. All fields in the oneof
176  * are added to the message descriptor. Sub-type references (e.g. for fields of
177  * type message) are not resolved at this point.
178  */
179  @JRubyMethod(name = "add_oneof")
180  public IRubyObject addOneof(ThreadContext context, IRubyObject obj) {
182  builder.addOneofDecl(def.build(builder.getOneofDeclCount()));
183  for (RubyFieldDescriptor fieldDescriptor : def.getFields()) {
184  addField(context, fieldDescriptor);
185  }
186  oneofDefs.put(def.getName(context), def);
187  return context.runtime.getNil();
188  }
189 
190  /*
191  * call-seq:
192  * Descriptor.each_oneof(&block) => nil
193  *
194  * Invokes the given block for each oneof in this message type, passing the
195  * corresponding OneofDescriptor.
196  */
197  @JRubyMethod(name = "each_oneof")
198  public IRubyObject eachOneof(ThreadContext context, Block block) {
199  for (RubyOneofDescriptor oneofDescriptor : oneofDefs.values()) {
200  block.yieldSpecific(context, oneofDescriptor);
201  }
202  return context.runtime.getNil();
203  }
204 
205  /*
206  * call-seq:
207  * Descriptor.lookup_oneof(name) => OneofDescriptor
208  *
209  * Returns the oneof descriptor for the oneof with the given name, if present,
210  * or nil if none.
211  */
212  @JRubyMethod(name = "lookup_oneof")
213  public IRubyObject lookupOneof(ThreadContext context, IRubyObject name) {
214  if (name instanceof RubySymbol) {
215  name = ((RubySymbol) name).id2name();
216  }
217  return oneofDefs.containsKey(name) ? oneofDefs.get(name) : context.runtime.getNil();
218  }
219 
221  this.descriptor = descriptor;
222  }
223 
225  return this.descriptor;
226  }
227 
228  public DescriptorProtos.DescriptorProto.Builder getBuilder() {
229  return builder;
230  }
231 
232  public void setMapEntry(boolean isMapEntry) {
233  this.builder.setOptions(DescriptorProtos.MessageOptions.newBuilder().setMapEntry(isMapEntry));
234  }
235 
236  private RubyModule buildClassFromDescriptor(ThreadContext context) {
237  Ruby runtime = context.runtime;
238 
239  ObjectAllocator allocator = new ObjectAllocator() {
240  @Override
241  public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
242  return new RubyMessage(runtime, klazz, descriptor);
243  }
244  };
245 
246  // rb_define_class_id
247  RubyClass klass = RubyClass.newClass(runtime, runtime.getObject());
248  klass.setAllocator(allocator);
249  klass.makeMetaClass(runtime.getObject().getMetaClass());
250  klass.inherit(runtime.getObject());
251  RubyModule messageExts = runtime.getClassFromPath("Google::Protobuf::MessageExts");
252  klass.include(new IRubyObject[] {messageExts});
253  klass.instance_variable_set(runtime.newString(Utils.DESCRIPTOR_INSTANCE_VAR), this);
254  klass.defineAnnotatedMethods(RubyMessage.class);
255  return klass;
256  }
257 
258  protected RubyFieldDescriptor lookup(String fieldName) {
259  return fieldDefMap.get(Utils.unescapeIdentifier(fieldName));
260  }
261 
262  private IRubyObject name;
263  private RubyModule klazz;
264 
265  private DescriptorProtos.DescriptorProto.Builder builder;
267  private Map<String, RubyFieldDescriptor> fieldDefMap;
268  private Map<IRubyObject, RubyOneofDescriptor> oneofDefs;
269 }
com.google.protobuf.jruby.RubyDescriptor.getBuilder
DescriptorProtos.DescriptorProto.Builder getBuilder()
Definition: RubyDescriptor.java:228
com.google.protobuf.Descriptors
Definition: Descriptors.java:80
Map
struct Map Map
Definition: php/ext/google/protobuf/protobuf.h:648
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
com.google.protobuf.jruby.Utils.escapeIdentifier
static String escapeIdentifier(String name)
Definition: Utils.java:217
com.google.protobuf.jruby.RubyDescriptor.descriptor
Descriptors.Descriptor descriptor
Definition: RubyDescriptor.java:266
com.google.protobuf.jruby.Utils
Definition: Utils.java:49
com.google.protobuf.jruby.RubyFieldDescriptor.build
DescriptorProtos.FieldDescriptorProto build()
Definition: RubyFieldDescriptor.java:262
com.google.protobuf.jruby.RubyDescriptor.setDescriptor
void setDescriptor(Descriptors.Descriptor descriptor)
Definition: RubyDescriptor.java:220
com.google.protobuf.jruby.RubyDescriptor.name
IRubyObject name
Definition: RubyDescriptor.java:262
com.google.protobuf.jruby.RubyDescriptor.RubyDescriptor
RubyDescriptor(Ruby runtime, RubyClass klazz)
Definition: RubyDescriptor.java:63
com.google.protobuf.jruby.RubyOneofDescriptor
Definition: RubyOneofDescriptor.java:19
com.google.protobuf
Definition: ProtoCaliperBenchmark.java:2
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
com.google.protobuf.jruby.RubyDescriptor.lookup
RubyFieldDescriptor lookup(String fieldName)
Definition: RubyDescriptor.java:258
com.google.protobuf.jruby.RubyOneofDescriptor.getName
IRubyObject getName(ThreadContext context)
Definition: RubyOneofDescriptor.java:51
com.google.protobuf.jruby.RubyDescriptor.fieldDefMap
Map< String, RubyFieldDescriptor > fieldDefMap
Definition: RubyDescriptor.java:267
com.google.protobuf.jruby.Utils.unescapeIdentifier
static String unescapeIdentifier(String name)
Definition: Utils.java:226
obj
GLsizei GLsizei GLuint * obj
Definition: glcorearb.h:3066
com.google.protobuf.jruby.RubyDescriptor.each
IRubyObject each(ThreadContext context, Block block)
Definition: RubyDescriptor.java:161
com.google.protobuf.jruby.RubyDescriptor.createRubyDescriptor
static void createRubyDescriptor(Ruby runtime)
Definition: RubyDescriptor.java:51
com.google.protobuf.jruby.RubyDescriptor.initialize
IRubyObject initialize(ThreadContext context)
Definition: RubyDescriptor.java:77
com.google.protobuf.jruby.RubyDescriptor.msgclass
IRubyObject msgclass(ThreadContext context)
Definition: RubyDescriptor.java:147
com.google.protobuf.jruby.RubyFieldDescriptor.getName
IRubyObject getName(ThreadContext context)
Definition: RubyFieldDescriptor.java:108
cDescriptor
VALUE cDescriptor
com.google.protobuf.jruby.Utils.DESCRIPTOR_INSTANCE_VAR
static String DESCRIPTOR_INSTANCE_VAR
Definition: Utils.java:296
com.google.protobuf.jruby.RubyFieldDescriptor
Definition: RubyFieldDescriptor.java:45
com.google.protobuf.jruby.RubyDescriptor.oneofDefs
Map< IRubyObject, RubyOneofDescriptor > oneofDefs
Definition: RubyDescriptor.java:268
java
com.google.protobuf.Descriptors.Descriptor
Definition: Descriptors.java:629
com.google.protobuf.jruby.RubyDescriptor.lookup
IRubyObject lookup(ThreadContext context, IRubyObject fieldName)
Definition: RubyDescriptor.java:135
com.google.protobuf.jruby.RubyOneofDescriptor.build
DescriptorProtos.OneofDescriptorProto build(int index)
Definition: RubyOneofDescriptor.java:105
com.google.protobuf.jruby.RubyDescriptor.klazz
RubyModule klazz
Definition: RubyDescriptor.java:263
com.google
com
com.google.protobuf.jruby.RubyMessage
Definition: RubyMessage.java:49
com.google.protobuf.jruby.RubyDescriptor.buildClassFromDescriptor
RubyModule buildClassFromDescriptor(ThreadContext context)
Definition: RubyDescriptor.java:236
com.google.protobuf.jruby.RubyDescriptor
Definition: RubyDescriptor.java:50
com.google.protobuf.jruby.RubyDescriptor.setMapEntry
void setMapEntry(boolean isMapEntry)
Definition: RubyDescriptor.java:232
com.google.protobuf::DescriptorProtos
com.google.protobuf.jruby.RubyOneofDescriptor.getFields
Collection< RubyFieldDescriptor > getFields()
Definition: RubyOneofDescriptor.java:112
klass
zend_class_entry * klass
Definition: php/ext/google/protobuf/protobuf.h:801
com.google.protobuf.jruby.RubyDescriptor.builder
DescriptorProtos.DescriptorProto.Builder builder
Definition: RubyDescriptor.java:265
com.google.protobuf.jruby.RubyDescriptor.getDescriptor
Descriptors.Descriptor getDescriptor()
Definition: RubyDescriptor.java:224


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:58