• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Protocol Buffers - Google's data interchange format
3  * Copyright 2024 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 
35 import com.google.protobuf.CodedInputStream;
36 import com.google.protobuf.Descriptors.MethodDescriptor;
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 import org.jruby.anno.JRubyClass;
45 import org.jruby.anno.JRubyMethod;
46 
47 @JRubyClass(name = "MethoDescriptor")
48 public class RubyMethodDescriptor extends RubyObject {
createRubyMethodDescriptor(Ruby runtime)49   public static void createRubyMethodDescriptor(Ruby runtime) {
50     RubyModule protobuf = runtime.getClassFromPath("Google::Protobuf");
51     RubyClass cMethodDescriptor =
52         protobuf.defineClassUnder(
53             "MethodDescriptor",
54             runtime.getObject(),
55             new ObjectAllocator() {
56               @Override
57               public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
58                 return new RubyMethodDescriptor(runtime, klazz);
59               }
60             });
61     cMethodDescriptor.defineAnnotatedMethods(RubyMethodDescriptor.class);
62   }
63 
RubyMethodDescriptor(Ruby runtime, RubyClass klazz)64   public RubyMethodDescriptor(Ruby runtime, RubyClass klazz) {
65     super(runtime, klazz);
66   }
67 
68   /*
69    * call-seq:
70    *     MethodDescriptor.name => name
71    *
72    * Returns the name of this method
73    */
74   @JRubyMethod(name = "name")
getName(ThreadContext context)75   public IRubyObject getName(ThreadContext context) {
76     return context.runtime.newString(this.descriptor.getName());
77   }
78 
79   /*
80    * call-seq:
81    *    MethodDescriptor.options
82    *
83    * Returns the options set on this protobuf rpc method
84    */
85   @JRubyMethod
options(ThreadContext context)86   public IRubyObject options(ThreadContext context) {
87     RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null);
88     RubyDescriptor methodOptionsDescriptor =
89         (RubyDescriptor)
90             pool.lookup(context, context.runtime.newString("google.protobuf.MethodOptions"));
91     RubyClass methodOptionsClass = (RubyClass) methodOptionsDescriptor.msgclass(context);
92     RubyMessage msg = (RubyMessage) methodOptionsClass.newInstance(context, Block.NULL_BLOCK);
93     return msg.decodeBytes(
94         context,
95         msg,
96         CodedInputStream.newInstance(
97             descriptor.getOptions().toByteString().toByteArray()), /*freeze*/
98         true);
99   }
100 
101   /*
102    * call-seq:
103    *      MethodDescriptor.input_type => Descriptor
104    *
105    * Returns the `Descriptor` for the request message type of this method
106    */
107   @JRubyMethod(name = "input_type")
getInputType(ThreadContext context)108   public IRubyObject getInputType(ThreadContext context) {
109     return this.pool.lookup(
110         context, context.runtime.newString(this.descriptor.getInputType().getFullName()));
111   }
112 
113   /*
114    * call-seq:
115    *      MethodDescriptor.output_type => Descriptor
116    *
117    * Returns the `Descriptor` for the response message type of this method
118    */
119   @JRubyMethod(name = "output_type")
getOutputType(ThreadContext context)120   public IRubyObject getOutputType(ThreadContext context) {
121     return this.pool.lookup(
122         context, context.runtime.newString(this.descriptor.getOutputType().getFullName()));
123   }
124 
125   /*
126    * call-seq:
127    *      MethodDescriptor.client_streaming => bool
128    *
129    * Returns whether or not this is a streaming request method
130    */
131   @JRubyMethod(name = "client_streaming")
getClientStreaming(ThreadContext context)132   public IRubyObject getClientStreaming(ThreadContext context) {
133     return this.descriptor.isClientStreaming()
134         ? context.runtime.getTrue()
135         : context.runtime.getFalse();
136   }
137 
138   /*
139    * call-seq:
140    *      MethodDescriptor.server_streaming => bool
141    *
142    * Returns whether or not this is a streaming response method
143    */
144   @JRubyMethod(name = "server_streaming")
getServerStreaming(ThreadContext context)145   public IRubyObject getServerStreaming(ThreadContext context) {
146     return this.descriptor.isServerStreaming()
147         ? context.runtime.getTrue()
148         : context.runtime.getFalse();
149   }
150 
setDescriptor( ThreadContext context, MethodDescriptor descriptor, RubyDescriptorPool pool)151   protected void setDescriptor(
152       ThreadContext context, MethodDescriptor descriptor, RubyDescriptorPool pool) {
153     this.descriptor = descriptor;
154     this.pool = pool;
155   }
156 
157   private MethodDescriptor descriptor;
158   private IRubyObject name;
159   private RubyDescriptorPool pool;
160 }
161