<commit_before>/*
 * Copyright 2016 Facebook, Inc.
 *
 * 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_mstch_generator.h>

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>

class t_mstch_swift_generator : public t_mstch_generator {
 public:
  t_mstch_swift_generator(
      t_program* program,
      const std::map<std::string, std::string>& parsed_options,
      const std::string& option_string)
      : t_mstch_generator(program, "java/swift", parsed_options) {
    this->out_dir_base_ = "gen-swift";
  }

  void generate_program() override;

 protected:
  /*
   * Generate multiple Java items according to the given template. Writes
   * output to package_dir underneath the global output directory.
   */
  template <typename T>
  void generate_items(
      const std::string& tpl_path,
      const std::vector<T*>& items) {
    auto& tpl = this->get_template(tpl_path);
    for (const T* item : items) {
      auto package_dir =
          package_to_path(item->get_program()->get_namespace("java.swift"));
      auto filename = this->mangle_java_name(item->get_name(), true) + ".java";
      auto rendered_item =
          mstch::render(tpl, this->dump(*item), this->get_template_map());
      this->write_output(package_dir / filename, rendered_item);
    }
  }

  void generate_constants(const t_program& prog) {
    if (prog.get_consts().empty()) {
      // Only generate Constants.java if we actually have constants
      return;
    }
    auto package_dir = package_to_path(prog.get_namespace("java.swift"));
    auto rendered = mstch::render(
        this->get_template("Constants"),
        this->dump(prog),
        this->get_template_map());
    this->write_output(package_dir / "Constants.java", rendered);
  }

  mstch::map extend_program(const t_program& program) const override {
    // Sort constant members to match java swift generator
    auto constants = program.get_consts();
    std::sort(
        constants.begin(),
        constants.end(),
        [](const t_const* x, const t_const* y) {
          return std::less<std::string>{}(x->get_name(), y->get_name());
        });
    return mstch::map{
        {"javaPackage", program.get_namespace("java.swift")},
        {"sortedConstants", this->dump_vector(constants)},
    };
  }

  mstch::map extend_struct(const t_struct& strct) const override {
    mstch::map result{
        {"javaPackage", strct.get_program()->get_namespace("java.swift")},
    };
    this->add_java_names(result, strct.get_name());
    return result;
  }

  mstch::map extend_service(const t_service& service) const override {
    mstch::map result{
        {"javaPackage", service.get_program()->get_namespace("java.swift")},
    };
    this->add_java_names(result, service.get_name());
    return result;
  }

  mstch::map extend_function(const t_function& func) const override {
    mstch::map result{};
    this->add_java_names(result, func.get_name());
    return result;
  }

  mstch::map extend_field(const t_field& field) const override {
    mstch::map result{};
    this->add_java_names(result, field.get_name());
    return result;
  }

  mstch::map extend_enum(const t_enum& enm) const override {
    mstch::map result{
        {"javaPackage", enm.get_program()->get_namespace("java.swift")},
    };
    this->add_java_names(result, enm.get_name());
    return result;
  }

  mstch::map extend_enum_value(const t_enum_value& value) const override {
    mstch::map result{};
    this->add_java_names(result, value.get_name());
    return result;
  }

  /**
   * Extend types to have a field set if the corresponding Java type has
   * a primitive representation. We need this because these types are treated
   * differently when they are arguments to type constructors in Java.
   */
  mstch::map extend_type(const t_type& type) const override {
    return mstch::map{<commit_msg>Implement missing flags for mstch swift generator<commit_after>/*
 * Copyright 2016 Facebook, Inc.
 *
 * 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_mstch_generator.h>

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>

#include <folly/Conv.h>
#include <folly/Optional.h>

class t_mstch_swift_generator : public t_mstch_generator {
 public:
  t_mstch_swift_generator(
      t_program* program,
      const std::map<std::string, std::string>& parsed_options,
      const std::string& option_string)
      : t_mstch_generator(program, "java/swift", parsed_options),
        default_package_(this->get_option("default_package")),
        namespace_identifier_(
            this->get_option("use_java_namespace") ? "java" : "java.swift") {
    this->out_dir_base_ = "gen-swift";
  }

  void generate_program() override;

 protected:
  const folly::Optional<std::string> default_package_;

  const std::string namespace_identifier_;

  /**
   * Gets the swift namespace, or, if it doesn't exist, uses the default.
   * If no default specified, throws runtime error
   */
  std::string get_namespace_or_default(const t_program& prog) const {
    const auto& prog_namespace =
        prog.get_namespace(this->namespace_identifier_);
    if (prog_namespace != "") {
      return prog_namespace;
    } else if (default_package_.hasValue()) {
      return default_package_.value();
    } else {
      throw std::runtime_error{folly::to<std::string>(
          "No namespace '",
          this->namespace_identifier_,
          "' in ",
          prog.get_name())};
    }
  }

  /*
   * Generate multiple Java items according to the given template. Writes
   * output to package_dir underneath the global output directory.
   */
  template <typename T>
  void generate_items(
      const std::string& tpl_path,
      const std::vector<T*>& items) {
    auto& tpl = this->get_template(tpl_path);
    for (const T* item : items) {
      auto package_dir =
          package_to_path(this->get_namespace_or_default(*item->get_program()));
      auto filename = this->mangle_java_name(item->get_name(), true) + ".java";
      auto rendered_item =
          mstch::render(tpl, this->dump(*item), this->get_template_map());
      this->write_output(package_dir / filename, rendered_item);
    }
  }

  void generate_constants(const t_program& prog) {
    if (prog.get_consts().empty()) {
      // Only generate Constants.java if we actually have constants
      return;
    }
    auto package_dir = package_to_path(this->get_namespace_or_default(prog));
    auto rendered = mstch::render(
        this->get_template("Constants"),
        this->dump(prog),
        this->get_template_map());
    this->write_output(package_dir / "Constants.java", rendered);
  }

  mstch::map extend_program(const t_program& program) const override {
    // Sort constant members to match java swift generator
    auto constants = program.get_consts();
    std::sort(
        constants.begin(),
        constants.end(),
        [](const t_const* x, const t_const* y) {
          return std::less<std::string>{}(x->get_name(), y->get_name());
        });
    return mstch::map{
        {"javaPackage", this->get_namespace_or_default(program)},
        {"sortedConstants", this->dump_vector(constants)},
    };
  }

  mstch::map extend_struct(const t_struct& strct) const override {
    mstch::map result{
        {"javaPackage", this->get_namespace_or_default(*strct.get_program())},
    };
    this->add_java_names(result, strct.get_name());
    return result;
  }

  mstch::map extend_service(const t_service& service) const override {
    mstch::map result{
        {"javaPackage", this->get_namespace_or_default(*service.get_program())},
    };
    this->add_java_names(result, service.get_name());
    return result;
  }

  mstch::map extend_function(const t_function& func) const override {
    mstch::map result{};
    this->add_java_names(result, func.get_name());
    return result;
  }

  mstch::map extend_field(const t_field& field) const override {
    mstch::map result{};
    this->add_java_names(result, field.get_name());
    return result;
  }

  mstch::map extend_enum(const t_enum& enm) const override {
    mstch::map result{
        {"javaPackage", this->get_namespace_or_default(*enm.get_program())},
    };
    this->add_java_names(result, enm.get_name());
    return result;
  }

  mstch::map extend_enum_value(const t_enum_value& value) const override {
    mstch::map result{};
    this->add_java_names(result, value.get_name());
    return result;
  }

  /**
   * Extend types to have a field set if the corresponding Java type has
   * a primitive representation. We need this because these types are treated
   * differently when they are arguments to type constructors in Java.
   */
  mstch::map extend_type(const t_type& type) const override {
    return mstch::map{
{'fraction_non_alphanumeric': 0.120966926266815, 'fraction_numerical': 0.0016182866390209367, 'mean_word_length': 3.607642124883504, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '524949', 'n_tokens_mistral': 3033, 'n_tokens_neox': 2977, 'n_words': 761}