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 #include <thrift/compiler/generate/t_mstch_objects.h>
18 
19 namespace apache {
20 namespace thrift {
21 namespace compiler {
22 
has_option(const std::string & option) const23 bool mstch_base::has_option(const std::string& option) const {
24   return cache_->parsed_options_.find(option) != cache_->parsed_options_.end();
25 }
26 
get_option(const std::string & option) const27 std::string mstch_base::get_option(const std::string& option) const {
28   auto itr = cache_->parsed_options_.find(option);
29   if (itr != cache_->parsed_options_.end()) {
30     return itr->second;
31   }
32   return {};
33 }
34 
register_has_option(std::string key,std::string option)35 void mstch_base::register_has_option(std::string key, std::string option) {
36   register_method(
37       std::move(key), [this, option = std::move(option)]() -> mstch::node {
38         return has_option(option);
39       });
40 }
41 
generate(t_enum_value const * enum_value,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const42 std::shared_ptr<mstch_base> enum_value_generator::generate(
43     t_enum_value const* enum_value,
44     std::shared_ptr<mstch_generators const> generators,
45     std::shared_ptr<mstch_cache> cache,
46     ELEMENT_POSITION pos,
47     int32_t /*index*/) const {
48   return std::make_shared<mstch_enum_value>(enum_value, generators, cache, pos);
49 }
50 
generate(t_enum const * enm,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const51 std::shared_ptr<mstch_base> enum_generator::generate(
52     t_enum const* enm,
53     std::shared_ptr<mstch_generators const> generators,
54     std::shared_ptr<mstch_cache> cache,
55     ELEMENT_POSITION pos,
56     int32_t /*index*/) const {
57   return std::make_shared<mstch_enum>(enm, generators, cache, pos);
58 }
59 
generate(t_const_value const * const_value,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t index,t_const const * current_const,t_type const * expected_type) const60 std::shared_ptr<mstch_base> const_value_generator::generate(
61     t_const_value const* const_value,
62     std::shared_ptr<mstch_generators const> generators,
63     std::shared_ptr<mstch_cache> cache,
64     ELEMENT_POSITION pos,
65     int32_t index,
66     t_const const* current_const,
67     t_type const* expected_type) const {
68   return std::make_shared<mstch_const_value>(
69       const_value, current_const, expected_type, generators, cache, pos, index);
70 }
71 
generate(std::pair<t_const_value *,t_const_value * > const & value_pair,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t index,t_const const * current_const,std::pair<const t_type *,const t_type * > const & expected_types) const72 std::shared_ptr<mstch_base> const_value_generator::generate(
73     std::pair<t_const_value*, t_const_value*> const& value_pair,
74     std::shared_ptr<mstch_generators const> generators,
75     std::shared_ptr<mstch_cache> cache,
76     ELEMENT_POSITION pos,
77     int32_t index,
78     t_const const* current_const,
79     std::pair<const t_type*, const t_type*> const& expected_types) const {
80   return std::make_shared<mstch_const_value_key_mapped_pair>(
81       value_pair, current_const, expected_types, generators, cache, pos, index);
82 }
83 
generate(t_type const * type,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const84 std::shared_ptr<mstch_base> type_generator::generate(
85     t_type const* type,
86     std::shared_ptr<mstch_generators const> generators,
87     std::shared_ptr<mstch_cache> cache,
88     ELEMENT_POSITION pos,
89     int32_t /*index*/) const {
90   return std::make_shared<mstch_type>(type, generators, cache, pos);
91 }
92 
generate(t_field const * field,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t index,field_generator_context const * field_context) const93 std::shared_ptr<mstch_base> field_generator::generate(
94     t_field const* field,
95     std::shared_ptr<mstch_generators const> generators,
96     std::shared_ptr<mstch_cache> cache,
97     ELEMENT_POSITION pos,
98     int32_t index,
99     field_generator_context const* field_context) const {
100   return std::make_shared<mstch_field>(
101       field, generators, cache, pos, index, field_context);
102 }
103 
generate(const t_annotation & annotation,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t index) const104 std::shared_ptr<mstch_base> annotation_generator::generate(
105     const t_annotation& annotation,
106     std::shared_ptr<mstch_generators const> generators,
107     std::shared_ptr<mstch_cache> cache,
108     ELEMENT_POSITION pos,
109     int32_t index) const {
110   return std::make_shared<mstch_annotation>(
111       annotation.first, annotation.second, generators, cache, pos, index);
112 }
113 
generate(const t_const * annotValue,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t index) const114 std::shared_ptr<mstch_base> structured_annotation_generator::generate(
115     const t_const* annotValue,
116     std::shared_ptr<mstch_generators const> generators,
117     std::shared_ptr<mstch_cache> cache,
118     ELEMENT_POSITION pos,
119     int32_t index) const {
120   return std::make_shared<mstch_structured_annotation>(
121       *annotValue, generators, cache, pos, index);
122 }
123 
generate(t_struct const * strct,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const124 std::shared_ptr<mstch_base> struct_generator::generate(
125     t_struct const* strct,
126     std::shared_ptr<mstch_generators const> generators,
127     std::shared_ptr<mstch_cache> cache,
128     ELEMENT_POSITION pos,
129     int32_t /*index*/) const {
130   return std::make_shared<mstch_struct>(strct, generators, cache, pos);
131 }
132 
generate(t_function const * function,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const133 std::shared_ptr<mstch_base> function_generator::generate(
134     t_function const* function,
135     std::shared_ptr<mstch_generators const> generators,
136     std::shared_ptr<mstch_cache> cache,
137     ELEMENT_POSITION pos,
138     int32_t /*index*/) const {
139   return std::make_shared<mstch_function>(function, generators, cache, pos);
140 }
141 
generate(t_service const * service,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const142 std::shared_ptr<mstch_base> service_generator::generate(
143     t_service const* service,
144     std::shared_ptr<mstch_generators const> generators,
145     std::shared_ptr<mstch_cache> cache,
146     ELEMENT_POSITION pos,
147     int32_t /*index*/) const {
148   return std::make_shared<mstch_service>(service, generators, cache, pos);
149 }
150 
generate(t_typedef const * typedf,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const151 std::shared_ptr<mstch_base> typedef_generator::generate(
152     t_typedef const* typedf,
153     std::shared_ptr<mstch_generators const> generators,
154     std::shared_ptr<mstch_cache> cache,
155     ELEMENT_POSITION pos,
156     int32_t /*index*/) const {
157   return std::make_shared<mstch_typedef>(typedf, generators, cache, pos);
158 }
159 
generate(t_const const * cnst,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t index,t_const const * current_const,t_type const * expected_type,t_field const * field) const160 std::shared_ptr<mstch_base> const_generator::generate(
161     t_const const* cnst,
162     std::shared_ptr<mstch_generators const> generators,
163     std::shared_ptr<mstch_cache> cache,
164     ELEMENT_POSITION pos,
165     int32_t index,
166     t_const const* current_const,
167     t_type const* expected_type,
168     t_field const* field) const {
169   return std::make_shared<mstch_const>(
170       cnst, current_const, expected_type, generators, cache, pos, index, field);
171 }
172 
generate(t_program const * program,std::shared_ptr<mstch_generators const> generators,std::shared_ptr<mstch_cache> cache,ELEMENT_POSITION pos,int32_t) const173 std::shared_ptr<mstch_base> program_generator::generate(
174     t_program const* program,
175     std::shared_ptr<mstch_generators const> generators,
176     std::shared_ptr<mstch_cache> cache,
177     ELEMENT_POSITION pos,
178     int32_t /*index*/) const {
179   return std::make_shared<mstch_program>(program, generators, cache, pos);
180 }
181 
values()182 mstch::node mstch_enum::values() {
183   return generate_enum_values(enm_->get_enum_values());
184 }
185 
get_struct()186 mstch::node mstch_type::get_struct() {
187   if (type_->is_struct() || type_->is_xception()) {
188     std::string id =
189         type_->program()->name() + get_type_namespace(type_->program());
190     return generate_elements_cached(
191         std::vector<t_struct const*>{dynamic_cast<t_struct const*>(type_)},
192         generators_->struct_generator_.get(),
193         cache_->structs_,
194         id);
195   }
196   return mstch::node();
197 }
198 
get_enum()199 mstch::node mstch_type::get_enum() {
200   if (resolved_type_->is_enum()) {
201     std::string id =
202         type_->program()->name() + get_type_namespace(type_->program());
203     return generate_elements_cached(
204         std::vector<t_enum const*>{dynamic_cast<t_enum const*>(resolved_type_)},
205         generators_->enum_generator_.get(),
206         cache_->enums_,
207         id);
208   }
209   return mstch::node();
210 }
211 
get_list_type()212 mstch::node mstch_type::get_list_type() {
213   if (resolved_type_->is_list()) {
214     return generators_->type_generator_->generate(
215         dynamic_cast<const t_list*>(resolved_type_)->get_elem_type(),
216         generators_,
217         cache_,
218         pos_);
219   }
220   return mstch::node();
221 }
222 
get_set_type()223 mstch::node mstch_type::get_set_type() {
224   if (resolved_type_->is_set()) {
225     return generators_->type_generator_->generate(
226         dynamic_cast<const t_set*>(resolved_type_)->get_elem_type(),
227         generators_,
228         cache_,
229         pos_);
230   }
231   return mstch::node();
232 }
233 
get_key_type()234 mstch::node mstch_type::get_key_type() {
235   if (resolved_type_->is_map()) {
236     return generators_->type_generator_->generate(
237         dynamic_cast<const t_map*>(resolved_type_)->get_key_type(),
238         generators_,
239         cache_,
240         pos_);
241   }
242   return mstch::node();
243 }
244 
get_value_type()245 mstch::node mstch_type::get_value_type() {
246   if (resolved_type_->is_map()) {
247     return generators_->type_generator_->generate(
248         dynamic_cast<const t_map*>(resolved_type_)->get_val_type(),
249         generators_,
250         cache_,
251         pos_);
252   }
253   return mstch::node();
254 }
255 
get_typedef_type()256 mstch::node mstch_type::get_typedef_type() {
257   if (type_->is_typedef()) {
258     return generators_->type_generator_->generate(
259         dynamic_cast<const t_typedef*>(type_)->get_type(),
260         generators_,
261         cache_,
262         pos_);
263   }
264   return mstch::node();
265 }
266 
get_typedef()267 mstch::node mstch_type::get_typedef() {
268   if (type_->is_typedef()) {
269     return generators_->typedef_generator_->generate(
270         dynamic_cast<const t_typedef*>(type_), generators_, cache_, pos_);
271   }
272   return mstch::node();
273 }
274 
get_sink_elem_type()275 mstch::node mstch_type::get_sink_elem_type() {
276   if (type_->is_sink()) {
277     return generators_->type_generator_->generate(
278         dynamic_cast<const t_sink*>(type_)->get_sink_type(),
279         generators_,
280         cache_,
281         pos_);
282   }
283   return mstch::node();
284 }
285 
get_sink_final_reponse_type()286 mstch::node mstch_type::get_sink_final_reponse_type() {
287   if (type_->is_sink()) {
288     return generators_->type_generator_->generate(
289         dynamic_cast<const t_sink*>(type_)->get_final_response_type(),
290         generators_,
291         cache_,
292         pos_);
293   }
294   return mstch::node();
295 }
296 
get_sink_first_response_type()297 mstch::node mstch_type::get_sink_first_response_type() {
298   if (type_->is_sink()) {
299     return generators_->type_generator_->generate(
300         dynamic_cast<const t_sink*>(type_)->get_first_response_type(),
301         generators_,
302         cache_,
303         pos_);
304   }
305   return mstch::node();
306 }
307 
get_stream_elem_type()308 mstch::node mstch_type::get_stream_elem_type() {
309   if (type_->is_streamresponse()) {
310     return generators_->type_generator_->generate(
311         dynamic_cast<const t_stream_response*>(type_)->get_elem_type(),
312         generators_,
313         cache_,
314         pos_);
315   }
316   return mstch::node();
317 }
318 
get_stream_first_response_type()319 mstch::node mstch_type::get_stream_first_response_type() {
320   if (resolved_type_->is_streamresponse()) {
321     return generators_->type_generator_->generate(
322         dynamic_cast<const t_stream_response*>(resolved_type_)
323             ->get_first_response_type(),
324         generators_,
325         cache_,
326         pos_);
327   }
328   return mstch::node();
329 }
330 
value()331 mstch::node mstch_field::value() {
332   if (field_->get_value()) {
333     return generators_->const_value_generator_->generate(
334         field_->get_value(), generators_, cache_, pos_);
335   }
336   return mstch::node();
337 }
338 
element_key()339 mstch::node mstch_const_value_key_mapped_pair::element_key() {
340   return generators_->const_value_generator_->generate(
341       pair_.first,
342       generators_,
343       cache_,
344       pos_,
345       index_,
346       current_const_,
347       expected_types_.first);
348 }
349 
element_value()350 mstch::node mstch_const_value_key_mapped_pair::element_value() {
351   return generators_->const_value_generator_->generate(
352       pair_.second,
353       generators_,
354       cache_,
355       pos_,
356       index_,
357       current_const_,
358       expected_types_.second);
359 }
360 
value()361 mstch::node mstch_const_value::value() {
362   switch (type_) {
363     case cv::CV_DOUBLE:
364       return format_double_string(const_value_->get_double());
365     case cv::CV_BOOL:
366       return std::to_string(const_value_->get_bool());
367     case cv::CV_INTEGER:
368       return std::to_string(const_value_->get_integer());
369     case cv::CV_STRING:
370       return const_value_->get_string();
371     default:
372       return mstch::node();
373   }
374 }
375 
integer_value()376 mstch::node mstch_const_value::integer_value() {
377   if (type_ == cv::CV_INTEGER) {
378     return std::to_string(const_value_->get_integer());
379   }
380   return mstch::node();
381 }
382 
double_value()383 mstch::node mstch_const_value::double_value() {
384   if (type_ == cv::CV_DOUBLE) {
385     return format_double_string(const_value_->get_double());
386   }
387   return mstch::node();
388 }
389 
bool_value()390 mstch::node mstch_const_value::bool_value() {
391   if (type_ == cv::CV_BOOL) {
392     return const_value_->get_bool() == true;
393   }
394   return mstch::node();
395 }
396 
is_non_zero()397 mstch::node mstch_const_value::is_non_zero() {
398   switch (type_) {
399     case cv::CV_DOUBLE:
400       return const_value_->get_double() != 0.0;
401     case cv::CV_BOOL:
402       return const_value_->get_bool() == true;
403     case cv::CV_INTEGER:
404       return const_value_->get_integer() != 0;
405     default:
406       return mstch::node();
407   }
408 }
409 
enum_name()410 mstch::node mstch_const_value::enum_name() {
411   if (type_ == cv::CV_INTEGER && const_value_->is_enum()) {
412     return const_value_->get_enum()->get_name();
413   }
414   return mstch::node();
415 }
416 
enum_value_name()417 mstch::node mstch_const_value::enum_value_name() {
418   if (type_ == cv::CV_INTEGER && const_value_->is_enum()) {
419     return const_value_->get_enum_value()->get_name();
420   }
421   return mstch::node();
422 }
423 
string_value()424 mstch::node mstch_const_value::string_value() {
425   if (type_ == cv::CV_STRING) {
426     std::string string_val = const_value_->get_string();
427     for (auto itr = string_val.begin(); itr != string_val.end(); ++itr) {
428       if (*itr == '"') {
429         itr = string_val.insert(itr, '\\');
430         ++itr;
431       }
432     }
433     return string_val;
434   }
435   return mstch::node();
436 }
437 
list_elems()438 mstch::node mstch_const_value::list_elems() {
439   if (type_ == cv::CV_LIST) {
440     const t_type* expected_type = nullptr;
441     if (expected_type_) {
442       if (expected_type_->is_list()) {
443         expected_type =
444             dynamic_cast<const t_list*>(expected_type_)->get_elem_type();
445       } else if (expected_type_->is_set()) {
446         expected_type =
447             dynamic_cast<const t_set*>(expected_type_)->get_elem_type();
448       }
449     }
450     return generate_consts(
451         const_value_->get_list(), current_const_, expected_type);
452   }
453   return mstch::node();
454 }
455 
map_elems()456 mstch::node mstch_const_value::map_elems() {
457   if (type_ == cv::CV_MAP) {
458     std::pair<const t_type*, const t_type*> expected_types;
459     if (expected_type_ && expected_type_->is_map()) {
460       const auto* m = dynamic_cast<const t_map*>(expected_type_);
461       expected_types = {m->get_key_type(), m->get_val_type()};
462     }
463     return generate_consts(
464         const_value_->get_map(), current_const_, expected_types);
465   }
466   return mstch::node();
467 }
468 
is_const_struct()469 mstch::node mstch_const_value::is_const_struct() {
470   if (!const_value_->ttype()) {
471     return false;
472   }
473   const auto* type = const_value_->ttype()->deref().get_true_type();
474   return type->is_struct() || type->is_xception();
475 }
476 
const_struct_type()477 mstch::node mstch_const_value::const_struct_type() {
478   if (!const_value_->ttype()) {
479     return {};
480   }
481 
482   const auto* type = const_value_->ttype()->deref().get_true_type();
483   if (type->is_struct() || type->is_xception()) {
484     return generators_->type_generator_->generate(type, generators_, cache_);
485   }
486 
487   return {};
488 }
489 
const_struct()490 mstch::node mstch_const_value::const_struct() {
491   std::vector<t_const*> constants;
492   std::vector<const t_field*> fields;
493   mstch::array a;
494 
495   const auto* type = const_value_->ttype()->deref().get_true_type();
496   if (type->is_struct() || type->is_xception()) {
497     auto const* strct = dynamic_cast<t_struct const*>(type);
498     for (auto member : const_value_->get_map()) {
499       auto const* field = strct->get_field_by_name(member.first->get_string());
500       assert(field != nullptr);
501       constants.push_back(new t_const(
502           nullptr,
503           field->get_type(),
504           field->get_name(),
505           member.second->clone()));
506       fields.push_back(field);
507     }
508   }
509 
510   for (size_t i = 0; i < constants.size(); ++i) {
511     auto pos = element_position(i, constants.size());
512     a.push_back(generators_->const_generator_->generate(
513         constants[i],
514         generators_,
515         cache_,
516         pos,
517         fields[i]->get_key(),
518         current_const_,
519         constants[i]->get_type(),
520         fields[i]));
521   }
522   return a;
523 }
524 
owning_const()525 mstch::node mstch_const_value::owning_const() {
526   return generators_->const_generator_->generate(
527       const_value_->get_owner(), generators_, cache_, pos_);
528 }
529 
type()530 mstch::node mstch_field::type() {
531   return generators_->type_generator_->generate(
532       field_->get_type(), generators_, cache_, pos_);
533 }
534 
fields()535 mstch::node mstch_struct::fields() {
536   return generate_fields(strct_->get_members());
537 }
538 
thrift_uri()539 mstch::node mstch_struct::thrift_uri() {
540   return strct_->get_annotation("thrift.uri");
541 }
542 
exception_safety()543 mstch::node mstch_struct::exception_safety() {
544   if (!strct_->is_xception()) {
545     return std::string("");
546   }
547 
548   const auto* t_ex_ptr = dynamic_cast<const t_exception*>(strct_);
549   auto s = t_ex_ptr->safety();
550 
551   switch (s) {
552     case t_error_safety::safe:
553       return std::string("SAFE");
554     default:
555       return std::string("UNSPECIFIED");
556   }
557 }
558 
exception_blame()559 mstch::node mstch_struct::exception_blame() {
560   if (!strct_->is_xception()) {
561     return std::string("");
562   }
563 
564   const auto* t_ex_ptr = dynamic_cast<const t_exception*>(strct_);
565   auto s = t_ex_ptr->blame();
566 
567   switch (s) {
568     case t_error_blame::server:
569       return std::string("SERVER");
570     case t_error_blame::client:
571       return std::string("CLIENT");
572     default:
573       return std::string("UNSPECIFIED");
574   }
575 }
576 
exception_kind()577 mstch::node mstch_struct::exception_kind() {
578   if (!strct_->is_xception()) {
579     return std::string("");
580   }
581 
582   const auto* t_ex_ptr = dynamic_cast<const t_exception*>(strct_);
583   auto s = t_ex_ptr->kind();
584 
585   switch (s) {
586     case t_error_kind::transient:
587       return std::string("TRANSIENT");
588     case t_error_kind::stateful:
589       return std::string("STATEFUL");
590     case t_error_kind::permanent:
591       return std::string("PERMANENT");
592     default:
593       return std::string("UNSPECIFIED");
594   }
595 }
596 
return_type()597 mstch::node mstch_function::return_type() {
598   return generators_->type_generator_->generate(
599       function_->get_returntype(), generators_, cache_, pos_);
600 }
601 
exceptions()602 mstch::node mstch_function::exceptions() {
603   return generate_fields(function_->get_xceptions()->get_members());
604 }
605 
stream_exceptions()606 mstch::node mstch_function::stream_exceptions() {
607   return generate_fields(function_->get_stream_xceptions()->get_members());
608 }
609 
sink_exceptions()610 mstch::node mstch_function::sink_exceptions() {
611   return generate_fields(function_->get_sink_xceptions()->get_members());
612 }
613 
sink_final_response_exceptions()614 mstch::node mstch_function::sink_final_response_exceptions() {
615   return generate_fields(
616       function_->get_sink_final_response_xceptions()->get_members());
617 }
618 
arg_list()619 mstch::node mstch_function::arg_list() {
620   return generate_fields(function_->get_paramlist()->get_members());
621 }
622 
returns_stream()623 mstch::node mstch_function::returns_stream() {
624   return function_->returns_stream();
625 }
626 
functions()627 mstch::node mstch_service::functions() {
628   return generate_functions(get_functions());
629 }
630 
extends()631 mstch::node mstch_service::extends() {
632   auto const* extends = service_->get_extends();
633   if (extends) {
634     return generate_cached_extended_service(extends);
635   }
636   return mstch::node();
637 }
638 
generate_cached_extended_service(const t_service * service)639 mstch::node mstch_service::generate_cached_extended_service(
640     const t_service* service) {
641   std::string id =
642       service->program()->name() + get_service_namespace(service->program());
643   size_t element_index = 0;
644   size_t element_count = 1;
645   return generate_element_cached(
646       service,
647       generators_->service_generator_.get(),
648       cache_->services_,
649       id,
650       element_index,
651       element_count);
652 }
653 
type()654 mstch::node mstch_typedef::type() {
655   return generators_->type_generator_->generate(
656       typedf_->get_type(), generators_, cache_, pos_);
657 }
658 
type()659 mstch::node mstch_const::type() {
660   return generators_->type_generator_->generate(
661       cnst_->get_type(), generators_, cache_, pos_);
662 }
663 
value()664 mstch::node mstch_const::value() {
665   return generators_->const_value_generator_->generate(
666       cnst_->get_value(), generators_, cache_, pos_, 0, cnst_, expected_type_);
667 }
668 
program()669 mstch::node mstch_const::program() {
670   return generators_->program_generator_->generate(
671       cnst_->get_program(), generators_, cache_, pos_);
672 }
673 
has_thrift_uris()674 mstch::node mstch_program::has_thrift_uris() {
675   for (const auto& strct : program_->structs()) {
676     if (strct->has_annotation("thrift.uri")) {
677       return true;
678     }
679   }
680   return false;
681 }
682 
structs()683 mstch::node mstch_program::structs() {
684   std::string id = program_->name() + get_program_namespace(program_);
685   return generate_elements_cached(
686       get_program_objects(),
687       generators_->struct_generator_.get(),
688       cache_->structs_,
689       id);
690 }
691 
enums()692 mstch::node mstch_program::enums() {
693   std::string id = program_->name() + get_program_namespace(program_);
694   return generate_elements_cached(
695       get_program_enums(),
696       generators_->enum_generator_.get(),
697       cache_->enums_,
698       id);
699 }
700 
services()701 mstch::node mstch_program::services() {
702   std::string id = program_->name() + get_program_namespace(program_);
703   return generate_elements_cached(
704       program_->services(),
705       generators_->service_generator_.get(),
706       cache_->services_,
707       id);
708 }
709 
typedefs()710 mstch::node mstch_program::typedefs() {
711   return generate_typedefs(program_->typedefs());
712 }
713 
constants()714 mstch::node mstch_program::constants() {
715   mstch::array a;
716   const auto& container = program_->consts();
717   for (size_t i = 0; i < container.size(); ++i) {
718     auto pos = element_position(i, container.size());
719     a.push_back(generators_->const_generator_->generate(
720         container[i],
721         generators_,
722         cache_,
723         pos,
724         i,
725         container[i],
726         container[i]->get_type()));
727   }
728   return a;
729 }
730 
get_program_objects()731 const std::vector<t_struct*>& mstch_program::get_program_objects() {
732   return program_->objects();
733 }
get_program_enums()734 const std::vector<t_enum*>& mstch_program::get_program_enums() {
735   return program_->enums();
736 }
737 
738 } // namespace compiler
739 } // namespace thrift
740 } // namespace apache
741