thrift/compiler/generate/t_generator.cc (83 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <thrift/compiler/generate/t_generator.h> #include <utility> #include <boost/algorithm/string/split.hpp> #include <thrift/compiler/common.h> namespace apache { namespace thrift { namespace compiler { t_generation_context::t_generation_context( std::string out_path, bool is_out_path_absolute) : out_path_(std::move(out_path)), is_out_path_absolute_(is_out_path_absolute) { if (!out_path_.empty()) { if (!(out_path_.back() == '/' || out_path_.back() == '\\')) { out_path_.push_back('/'); } } } t_generator::t_generator(t_program* program, t_generation_context context) : program_(program), context_(std::move(context)) { program_name_ = get_program_name(program_); } void t_generator_registry::register_generator(t_generator_factory* factory) { gen_map_t& the_map = get_generator_map(); if (the_map.find(factory->get_short_name()) != the_map.end()) { failure( "Duplicate generators for language \"%s\"!\n", factory->get_short_name().c_str()); } the_map[factory->get_short_name()] = factory; } t_generator* t_generator_registry::get_generator( t_program* program, t_generation_context context, const std::string& options) { std::string::size_type colon = options.find(':'); std::string language = options.substr(0, colon); std::map<std::string, std::string> parsed_options; parse_generator_options( options.substr(colon + 1), [&](std::string k, std::string v) { parsed_options[std::move(k)] = std::move(v); return CallbackLoopControl::Continue; }); gen_map_t& the_map = get_generator_map(); gen_map_t::iterator iter = the_map.find(language); if (iter == the_map.end()) { return nullptr; } return iter->second->get_generator(program, context, parsed_options, options); } t_generator_registry::gen_map_t& t_generator_registry::get_generator_map() { // http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 static gen_map_t* the_map = new gen_map_t(); return *the_map; } t_generator_factory::t_generator_factory( std::string short_name, std::string long_name, std::string documentation) : short_name_(std::move(short_name)), long_name_(std::move(long_name)), documentation_(std::move(documentation)) { t_generator_registry::register_generator(this); } void parse_generator_options( const std::string& options, std::function<CallbackLoopControl(std::string, std::string)> callback) { std::vector<std::string> parts; bool inside_braces = false; boost::algorithm::split(parts, options, [&inside_braces](char c) { if (c == '{' || c == '}') { inside_braces = (c == '{'); } return c == ',' && !inside_braces; }); for (const auto& part : parts) { auto key = part.substr(0, part.find('=')); auto value = part.substr(std::min(key.size() + 1, part.size())); if (callback(std::move(key), std::move(value)) == CallbackLoopControl::Break) { break; } } } } // namespace compiler } // namespace thrift } // namespace apache