1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include <boost/optional.hpp>
24 
25 #include <thrift/compiler/ast/t_throws.h>
26 #include <thrift/compiler/ast/t_type.h>
27 
28 namespace apache {
29 namespace thrift {
30 namespace compiler {
31 
32 /**
33  * A sink contains the types for stream of responses and a final response.
34  *
35  * Exceptions throw during the stream or instead of the final response can also
36  * be specified.
37  */
38 class t_sink : public t_templated_type {
39  public:
t_sink(t_type_ref sink_type,t_type_ref final_response_type)40   explicit t_sink(t_type_ref sink_type, t_type_ref final_response_type)
41       : sink_type_(std::move(sink_type)),
42         final_response_type_(std::move(final_response_type)) {}
43 
sink_type()44   const t_type_ref& sink_type() const { return sink_type_; }
final_response_type()45   const t_type_ref& final_response_type() const { return final_response_type_; }
46 
47   // Returns nullptr when throws clause is absent.
sink_exceptions()48   t_throws* sink_exceptions() { return sink_exceptions_.get(); }
sink_exceptions()49   const t_throws* sink_exceptions() const { return sink_exceptions_.get(); }
50   // Use nullptr to indicate an absent throws clause.
set_sink_exceptions(std::unique_ptr<t_throws> sink_exceptions)51   void set_sink_exceptions(std::unique_ptr<t_throws> sink_exceptions) {
52     sink_exceptions_ = std::move(sink_exceptions);
53   }
54 
55   // Returns nullptr when throws clause is absent.
final_response_exceptions()56   t_throws* final_response_exceptions() {
57     return final_response_exceptions_.get();
58   }
final_response_exceptions()59   const t_throws* final_response_exceptions() const {
60     return final_response_exceptions_.get();
61   }
62   // Use nullptr to indicate an absent throws clause.
set_final_response_exceptions(std::unique_ptr<t_throws> final_response_exceptions)63   void set_final_response_exceptions(
64       std::unique_ptr<t_throws> final_response_exceptions) {
65     final_response_exceptions_ = std::move(final_response_exceptions);
66   }
67 
set_first_response_type(boost::optional<t_type_ref> first_response)68   void set_first_response_type(boost::optional<t_type_ref> first_response) {
69     first_response_type_ = std::move(first_response);
70   }
first_response_type()71   const boost::optional<t_type_ref>& first_response_type() const {
72     return first_response_type_;
73   }
74 
get_full_name()75   std::string get_full_name() const override {
76     std::string result = "sink<" + sink_type_->get_full_name() + ", " +
77         final_response_type_->get_full_name() + ">";
78     if (first_response_type_ != boost::none) {
79       result += ", " + first_response_type_->deref().get_full_name();
80     }
81     return result;
82   }
83 
84  private:
85   t_type_ref sink_type_;
86   std::unique_ptr<t_throws> sink_exceptions_;
87   t_type_ref final_response_type_;
88   std::unique_ptr<t_throws> final_response_exceptions_;
89   boost::optional<t_type_ref> first_response_type_;
90 
91  public:
92   // TODO(afuller): Delete everything below here. It is only provided for
93   // backwards compatibility.
94 
t_sink(const t_type * sink_type,std::unique_ptr<t_throws> sink_exceptions,const t_type * final_response_type,std::unique_ptr<t_throws> final_response_exceptions)95   explicit t_sink(
96       const t_type* sink_type,
97       std::unique_ptr<t_throws> sink_exceptions,
98       const t_type* final_response_type,
99       std::unique_ptr<t_throws> final_response_exceptions)
100       : t_sink(
101             t_type_ref::from_req_ptr(sink_type),
102             t_type_ref::from_req_ptr(final_response_type)) {
103     set_sink_exceptions(std::move(sink_exceptions));
104     set_final_response_exceptions(std::move(final_response_exceptions));
105   }
106 
set_first_response(const t_type * first_response)107   void set_first_response(const t_type* first_response) {
108     set_first_response_type(t_type_ref::from_ptr(first_response));
109   }
110 
sink_has_first_response()111   bool sink_has_first_response() const {
112     return first_response_type_ != boost::none;
113   }
get_final_response_xceptions()114   t_throws* get_final_response_xceptions() const {
115     return final_response_exceptions_.get();
116   }
get_sink_xceptions()117   t_throws* get_sink_xceptions() const { return sink_exceptions_.get(); }
get_sink_type()118   const t_type* get_sink_type() const { return sink_type().get_type(); }
get_first_response_type()119   const t_type* get_first_response_type() const {
120     return first_response_type_ == boost::none
121         ? nullptr
122         : first_response_type_->get_type();
123   }
get_final_response_type()124   const t_type* get_final_response_type() const {
125     return final_response_type().get_type();
126   }
127 
is_sink()128   bool is_sink() const override { return true; }
get_type_value()129   type get_type_value() const override { return type::t_sink; }
130 };
131 
132 } // namespace compiler
133 } // namespace thrift
134 } // namespace apache
135