/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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.
 */

// automatically generated by the FlatBuffers compiler, do not modify


#ifndef FLATBUFFERS_GENERATED_MODEL_LIBTEXTCLASSIFIER2_FEATUREPROCESSOROPTIONS__H_
#define FLATBUFFERS_GENERATED_MODEL_LIBTEXTCLASSIFIER2_FEATUREPROCESSOROPTIONS__H_

#include "flatbuffers/flatbuffers.h"

namespace libtextclassifier2 {

struct SelectionModelOptions;
struct SelectionModelOptionsT;

struct ClassificationModelOptions;
struct ClassificationModelOptionsT;

struct RegexModelOptions;
struct RegexModelOptionsT;

namespace RegexModelOptions_ {

struct Pattern;
struct PatternT;

}  // namespace RegexModelOptions_

struct StructuredRegexModel;
struct StructuredRegexModelT;

namespace StructuredRegexModel_ {

struct StructuredPattern;
struct StructuredPatternT;

}  // namespace StructuredRegexModel_

struct Model;
struct ModelT;

struct TokenizationCodepointRange;
struct TokenizationCodepointRangeT;

struct FeatureProcessorOptions;
struct FeatureProcessorOptionsT;

namespace FeatureProcessorOptions_ {

struct CodepointRange;
struct CodepointRangeT;

struct CollectionMapEntry;
struct CollectionMapEntryT;

struct BoundsSensitiveFeatures;
struct BoundsSensitiveFeaturesT;

}  // namespace FeatureProcessorOptions_

namespace TokenizationCodepointRange_ {

enum Role {
  Role_DEFAULT_ROLE = 0,
  Role_SPLIT_BEFORE = 1,
  Role_SPLIT_AFTER = 2,
  Role_TOKEN_SEPARATOR = 3,
  Role_DISCARD_CODEPOINT = 4,
  Role_WHITESPACE_SEPARATOR = 7,
  Role_MIN = Role_DEFAULT_ROLE,
  Role_MAX = Role_WHITESPACE_SEPARATOR
};

inline Role (&EnumValuesRole())[6] {
  static Role values[] = {
    Role_DEFAULT_ROLE,
    Role_SPLIT_BEFORE,
    Role_SPLIT_AFTER,
    Role_TOKEN_SEPARATOR,
    Role_DISCARD_CODEPOINT,
    Role_WHITESPACE_SEPARATOR
  };
  return values;
}

inline const char **EnumNamesRole() {
  static const char *names[] = {
    "DEFAULT_ROLE",
    "SPLIT_BEFORE",
    "SPLIT_AFTER",
    "TOKEN_SEPARATOR",
    "DISCARD_CODEPOINT",
    "",
    "",
    "WHITESPACE_SEPARATOR",
    nullptr
  };
  return names;
}

inline const char *EnumNameRole(Role e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesRole()[index];
}

}  // namespace TokenizationCodepointRange_

namespace FeatureProcessorOptions_ {

enum CenterTokenSelectionMethod {
  CenterTokenSelectionMethod_DEFAULT_CENTER_TOKEN_METHOD = 0,
  CenterTokenSelectionMethod_CENTER_TOKEN_FROM_CLICK = 1,
  CenterTokenSelectionMethod_CENTER_TOKEN_MIDDLE_OF_SELECTION = 2,
  CenterTokenSelectionMethod_MIN = CenterTokenSelectionMethod_DEFAULT_CENTER_TOKEN_METHOD,
  CenterTokenSelectionMethod_MAX = CenterTokenSelectionMethod_CENTER_TOKEN_MIDDLE_OF_SELECTION
};

inline CenterTokenSelectionMethod (&EnumValuesCenterTokenSelectionMethod())[3] {
  static CenterTokenSelectionMethod values[] = {
    CenterTokenSelectionMethod_DEFAULT_CENTER_TOKEN_METHOD,
    CenterTokenSelectionMethod_CENTER_TOKEN_FROM_CLICK,
    CenterTokenSelectionMethod_CENTER_TOKEN_MIDDLE_OF_SELECTION
  };
  return values;
}

inline const char **EnumNamesCenterTokenSelectionMethod() {
  static const char *names[] = {
    "DEFAULT_CENTER_TOKEN_METHOD",
    "CENTER_TOKEN_FROM_CLICK",
    "CENTER_TOKEN_MIDDLE_OF_SELECTION",
    nullptr
  };
  return names;
}

inline const char *EnumNameCenterTokenSelectionMethod(CenterTokenSelectionMethod e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesCenterTokenSelectionMethod()[index];
}

enum TokenizationType {
  TokenizationType_INVALID_TOKENIZATION_TYPE = 0,
  TokenizationType_INTERNAL_TOKENIZER = 1,
  TokenizationType_ICU = 2,
  TokenizationType_MIXED = 3,
  TokenizationType_MIN = TokenizationType_INVALID_TOKENIZATION_TYPE,
  TokenizationType_MAX = TokenizationType_MIXED
};

inline TokenizationType (&EnumValuesTokenizationType())[4] {
  static TokenizationType values[] = {
    TokenizationType_INVALID_TOKENIZATION_TYPE,
    TokenizationType_INTERNAL_TOKENIZER,
    TokenizationType_ICU,
    TokenizationType_MIXED
  };
  return values;
}

inline const char **EnumNamesTokenizationType() {
  static const char *names[] = {
    "INVALID_TOKENIZATION_TYPE",
    "INTERNAL_TOKENIZER",
    "ICU",
    "MIXED",
    nullptr
  };
  return names;
}

inline const char *EnumNameTokenizationType(TokenizationType e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesTokenizationType()[index];
}

}  // namespace FeatureProcessorOptions_

struct SelectionModelOptionsT : public flatbuffers::NativeTable {
  typedef SelectionModelOptions TableType;
  bool strip_unpaired_brackets;
  int32_t symmetry_context_size;
  SelectionModelOptionsT()
      : strip_unpaired_brackets(false),
        symmetry_context_size(0) {
  }
};

struct SelectionModelOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SelectionModelOptionsT NativeTableType;
  enum {
    VT_STRIP_UNPAIRED_BRACKETS = 4,
    VT_SYMMETRY_CONTEXT_SIZE = 6
  };
  bool strip_unpaired_brackets() const {
    return GetField<uint8_t>(VT_STRIP_UNPAIRED_BRACKETS, 0) != 0;
  }
  int32_t symmetry_context_size() const {
    return GetField<int32_t>(VT_SYMMETRY_CONTEXT_SIZE, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_STRIP_UNPAIRED_BRACKETS) &&
           VerifyField<int32_t>(verifier, VT_SYMMETRY_CONTEXT_SIZE) &&
           verifier.EndTable();
  }
  SelectionModelOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(SelectionModelOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<SelectionModelOptions> Pack(flatbuffers::FlatBufferBuilder &_fbb, const SelectionModelOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct SelectionModelOptionsBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_strip_unpaired_brackets(bool strip_unpaired_brackets) {
    fbb_.AddElement<uint8_t>(SelectionModelOptions::VT_STRIP_UNPAIRED_BRACKETS, static_cast<uint8_t>(strip_unpaired_brackets), 0);
  }
  void add_symmetry_context_size(int32_t symmetry_context_size) {
    fbb_.AddElement<int32_t>(SelectionModelOptions::VT_SYMMETRY_CONTEXT_SIZE, symmetry_context_size, 0);
  }
  explicit SelectionModelOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SelectionModelOptionsBuilder &operator=(const SelectionModelOptionsBuilder &);
  flatbuffers::Offset<SelectionModelOptions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SelectionModelOptions>(end);
    return o;
  }
};

inline flatbuffers::Offset<SelectionModelOptions> CreateSelectionModelOptions(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool strip_unpaired_brackets = false,
    int32_t symmetry_context_size = 0) {
  SelectionModelOptionsBuilder builder_(_fbb);
  builder_.add_symmetry_context_size(symmetry_context_size);
  builder_.add_strip_unpaired_brackets(strip_unpaired_brackets);
  return builder_.Finish();
}

flatbuffers::Offset<SelectionModelOptions> CreateSelectionModelOptions(flatbuffers::FlatBufferBuilder &_fbb, const SelectionModelOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct ClassificationModelOptionsT : public flatbuffers::NativeTable {
  typedef ClassificationModelOptions TableType;
  int32_t phone_min_num_digits;
  int32_t phone_max_num_digits;
  ClassificationModelOptionsT()
      : phone_min_num_digits(7),
        phone_max_num_digits(15) {
  }
};

struct ClassificationModelOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ClassificationModelOptionsT NativeTableType;
  enum {
    VT_PHONE_MIN_NUM_DIGITS = 4,
    VT_PHONE_MAX_NUM_DIGITS = 6
  };
  int32_t phone_min_num_digits() const {
    return GetField<int32_t>(VT_PHONE_MIN_NUM_DIGITS, 7);
  }
  int32_t phone_max_num_digits() const {
    return GetField<int32_t>(VT_PHONE_MAX_NUM_DIGITS, 15);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_PHONE_MIN_NUM_DIGITS) &&
           VerifyField<int32_t>(verifier, VT_PHONE_MAX_NUM_DIGITS) &&
           verifier.EndTable();
  }
  ClassificationModelOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(ClassificationModelOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<ClassificationModelOptions> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ClassificationModelOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct ClassificationModelOptionsBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_phone_min_num_digits(int32_t phone_min_num_digits) {
    fbb_.AddElement<int32_t>(ClassificationModelOptions::VT_PHONE_MIN_NUM_DIGITS, phone_min_num_digits, 7);
  }
  void add_phone_max_num_digits(int32_t phone_max_num_digits) {
    fbb_.AddElement<int32_t>(ClassificationModelOptions::VT_PHONE_MAX_NUM_DIGITS, phone_max_num_digits, 15);
  }
  explicit ClassificationModelOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ClassificationModelOptionsBuilder &operator=(const ClassificationModelOptionsBuilder &);
  flatbuffers::Offset<ClassificationModelOptions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ClassificationModelOptions>(end);
    return o;
  }
};

inline flatbuffers::Offset<ClassificationModelOptions> CreateClassificationModelOptions(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t phone_min_num_digits = 7,
    int32_t phone_max_num_digits = 15) {
  ClassificationModelOptionsBuilder builder_(_fbb);
  builder_.add_phone_max_num_digits(phone_max_num_digits);
  builder_.add_phone_min_num_digits(phone_min_num_digits);
  return builder_.Finish();
}

flatbuffers::Offset<ClassificationModelOptions> CreateClassificationModelOptions(flatbuffers::FlatBufferBuilder &_fbb, const ClassificationModelOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct RegexModelOptionsT : public flatbuffers::NativeTable {
  typedef RegexModelOptions TableType;
  std::vector<std::unique_ptr<libtextclassifier2::RegexModelOptions_::PatternT>> patterns;
  RegexModelOptionsT() {
  }
};

struct RegexModelOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef RegexModelOptionsT NativeTableType;
  enum {
    VT_PATTERNS = 4
  };
  const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::RegexModelOptions_::Pattern>> *patterns() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::RegexModelOptions_::Pattern>> *>(VT_PATTERNS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PATTERNS) &&
           verifier.Verify(patterns()) &&
           verifier.VerifyVectorOfTables(patterns()) &&
           verifier.EndTable();
  }
  RegexModelOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(RegexModelOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<RegexModelOptions> Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegexModelOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct RegexModelOptionsBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_patterns(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::RegexModelOptions_::Pattern>>> patterns) {
    fbb_.AddOffset(RegexModelOptions::VT_PATTERNS, patterns);
  }
  explicit RegexModelOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RegexModelOptionsBuilder &operator=(const RegexModelOptionsBuilder &);
  flatbuffers::Offset<RegexModelOptions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<RegexModelOptions>(end);
    return o;
  }
};

inline flatbuffers::Offset<RegexModelOptions> CreateRegexModelOptions(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::RegexModelOptions_::Pattern>>> patterns = 0) {
  RegexModelOptionsBuilder builder_(_fbb);
  builder_.add_patterns(patterns);
  return builder_.Finish();
}

inline flatbuffers::Offset<RegexModelOptions> CreateRegexModelOptionsDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<libtextclassifier2::RegexModelOptions_::Pattern>> *patterns = nullptr) {
  return libtextclassifier2::CreateRegexModelOptions(
      _fbb,
      patterns ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::RegexModelOptions_::Pattern>>(*patterns) : 0);
}

flatbuffers::Offset<RegexModelOptions> CreateRegexModelOptions(flatbuffers::FlatBufferBuilder &_fbb, const RegexModelOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

namespace RegexModelOptions_ {

struct PatternT : public flatbuffers::NativeTable {
  typedef Pattern TableType;
  std::string collection_name;
  std::string pattern;
  PatternT() {
  }
};

struct Pattern FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PatternT NativeTableType;
  enum {
    VT_COLLECTION_NAME = 4,
    VT_PATTERN = 6
  };
  const flatbuffers::String *collection_name() const {
    return GetPointer<const flatbuffers::String *>(VT_COLLECTION_NAME);
  }
  const flatbuffers::String *pattern() const {
    return GetPointer<const flatbuffers::String *>(VT_PATTERN);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_COLLECTION_NAME) &&
           verifier.Verify(collection_name()) &&
           VerifyOffset(verifier, VT_PATTERN) &&
           verifier.Verify(pattern()) &&
           verifier.EndTable();
  }
  PatternT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(PatternT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<Pattern> Pack(flatbuffers::FlatBufferBuilder &_fbb, const PatternT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct PatternBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_collection_name(flatbuffers::Offset<flatbuffers::String> collection_name) {
    fbb_.AddOffset(Pattern::VT_COLLECTION_NAME, collection_name);
  }
  void add_pattern(flatbuffers::Offset<flatbuffers::String> pattern) {
    fbb_.AddOffset(Pattern::VT_PATTERN, pattern);
  }
  explicit PatternBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PatternBuilder &operator=(const PatternBuilder &);
  flatbuffers::Offset<Pattern> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Pattern>(end);
    return o;
  }
};

inline flatbuffers::Offset<Pattern> CreatePattern(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> collection_name = 0,
    flatbuffers::Offset<flatbuffers::String> pattern = 0) {
  PatternBuilder builder_(_fbb);
  builder_.add_pattern(pattern);
  builder_.add_collection_name(collection_name);
  return builder_.Finish();
}

inline flatbuffers::Offset<Pattern> CreatePatternDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *collection_name = nullptr,
    const char *pattern = nullptr) {
  return libtextclassifier2::RegexModelOptions_::CreatePattern(
      _fbb,
      collection_name ? _fbb.CreateString(collection_name) : 0,
      pattern ? _fbb.CreateString(pattern) : 0);
}

flatbuffers::Offset<Pattern> CreatePattern(flatbuffers::FlatBufferBuilder &_fbb, const PatternT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

}  // namespace RegexModelOptions_

struct StructuredRegexModelT : public flatbuffers::NativeTable {
  typedef StructuredRegexModel TableType;
  std::vector<std::unique_ptr<libtextclassifier2::StructuredRegexModel_::StructuredPatternT>> patterns;
  StructuredRegexModelT() {
  }
};

struct StructuredRegexModel FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StructuredRegexModelT NativeTableType;
  enum {
    VT_PATTERNS = 4
  };
  const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::StructuredRegexModel_::StructuredPattern>> *patterns() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::StructuredRegexModel_::StructuredPattern>> *>(VT_PATTERNS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PATTERNS) &&
           verifier.Verify(patterns()) &&
           verifier.VerifyVectorOfTables(patterns()) &&
           verifier.EndTable();
  }
  StructuredRegexModelT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(StructuredRegexModelT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<StructuredRegexModel> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StructuredRegexModelT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct StructuredRegexModelBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_patterns(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::StructuredRegexModel_::StructuredPattern>>> patterns) {
    fbb_.AddOffset(StructuredRegexModel::VT_PATTERNS, patterns);
  }
  explicit StructuredRegexModelBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StructuredRegexModelBuilder &operator=(const StructuredRegexModelBuilder &);
  flatbuffers::Offset<StructuredRegexModel> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StructuredRegexModel>(end);
    return o;
  }
};

inline flatbuffers::Offset<StructuredRegexModel> CreateStructuredRegexModel(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::StructuredRegexModel_::StructuredPattern>>> patterns = 0) {
  StructuredRegexModelBuilder builder_(_fbb);
  builder_.add_patterns(patterns);
  return builder_.Finish();
}

inline flatbuffers::Offset<StructuredRegexModel> CreateStructuredRegexModelDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<libtextclassifier2::StructuredRegexModel_::StructuredPattern>> *patterns = nullptr) {
  return libtextclassifier2::CreateStructuredRegexModel(
      _fbb,
      patterns ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::StructuredRegexModel_::StructuredPattern>>(*patterns) : 0);
}

flatbuffers::Offset<StructuredRegexModel> CreateStructuredRegexModel(flatbuffers::FlatBufferBuilder &_fbb, const StructuredRegexModelT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

namespace StructuredRegexModel_ {

struct StructuredPatternT : public flatbuffers::NativeTable {
  typedef StructuredPattern TableType;
  std::string pattern;
  std::vector<std::string> node_names;
  StructuredPatternT() {
  }
};

struct StructuredPattern FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef StructuredPatternT NativeTableType;
  enum {
    VT_PATTERN = 4,
    VT_NODE_NAMES = 6
  };
  const flatbuffers::String *pattern() const {
    return GetPointer<const flatbuffers::String *>(VT_PATTERN);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *node_names() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_NODE_NAMES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PATTERN) &&
           verifier.Verify(pattern()) &&
           VerifyOffset(verifier, VT_NODE_NAMES) &&
           verifier.Verify(node_names()) &&
           verifier.VerifyVectorOfStrings(node_names()) &&
           verifier.EndTable();
  }
  StructuredPatternT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(StructuredPatternT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<StructuredPattern> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StructuredPatternT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct StructuredPatternBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_pattern(flatbuffers::Offset<flatbuffers::String> pattern) {
    fbb_.AddOffset(StructuredPattern::VT_PATTERN, pattern);
  }
  void add_node_names(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> node_names) {
    fbb_.AddOffset(StructuredPattern::VT_NODE_NAMES, node_names);
  }
  explicit StructuredPatternBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  StructuredPatternBuilder &operator=(const StructuredPatternBuilder &);
  flatbuffers::Offset<StructuredPattern> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<StructuredPattern>(end);
    return o;
  }
};

inline flatbuffers::Offset<StructuredPattern> CreateStructuredPattern(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> pattern = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> node_names = 0) {
  StructuredPatternBuilder builder_(_fbb);
  builder_.add_node_names(node_names);
  builder_.add_pattern(pattern);
  return builder_.Finish();
}

inline flatbuffers::Offset<StructuredPattern> CreateStructuredPatternDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *pattern = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *node_names = nullptr) {
  return libtextclassifier2::StructuredRegexModel_::CreateStructuredPattern(
      _fbb,
      pattern ? _fbb.CreateString(pattern) : 0,
      node_names ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*node_names) : 0);
}

flatbuffers::Offset<StructuredPattern> CreateStructuredPattern(flatbuffers::FlatBufferBuilder &_fbb, const StructuredPatternT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

}  // namespace StructuredRegexModel_

struct ModelT : public flatbuffers::NativeTable {
  typedef Model TableType;
  std::string language;
  int32_t version;
  std::unique_ptr<FeatureProcessorOptionsT> selection_feature_options;
  std::unique_ptr<FeatureProcessorOptionsT> classification_feature_options;
  std::vector<uint8_t> selection_model;
  std::vector<uint8_t> classification_model;
  std::vector<uint8_t> embedding_model;
  std::unique_ptr<RegexModelOptionsT> regex_options;
  std::unique_ptr<SelectionModelOptionsT> selection_options;
  std::unique_ptr<ClassificationModelOptionsT> classification_options;
  std::unique_ptr<StructuredRegexModelT> regex_model;
  ModelT()
      : version(0) {
  }
};

struct Model FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ModelT NativeTableType;
  enum {
    VT_LANGUAGE = 4,
    VT_VERSION = 6,
    VT_SELECTION_FEATURE_OPTIONS = 8,
    VT_CLASSIFICATION_FEATURE_OPTIONS = 10,
    VT_SELECTION_MODEL = 12,
    VT_CLASSIFICATION_MODEL = 14,
    VT_EMBEDDING_MODEL = 16,
    VT_REGEX_OPTIONS = 18,
    VT_SELECTION_OPTIONS = 20,
    VT_CLASSIFICATION_OPTIONS = 22,
    VT_REGEX_MODEL = 24
  };
  const flatbuffers::String *language() const {
    return GetPointer<const flatbuffers::String *>(VT_LANGUAGE);
  }
  int32_t version() const {
    return GetField<int32_t>(VT_VERSION, 0);
  }
  const FeatureProcessorOptions *selection_feature_options() const {
    return GetPointer<const FeatureProcessorOptions *>(VT_SELECTION_FEATURE_OPTIONS);
  }
  const FeatureProcessorOptions *classification_feature_options() const {
    return GetPointer<const FeatureProcessorOptions *>(VT_CLASSIFICATION_FEATURE_OPTIONS);
  }
  const flatbuffers::Vector<uint8_t> *selection_model() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_SELECTION_MODEL);
  }
  const flatbuffers::Vector<uint8_t> *classification_model() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_CLASSIFICATION_MODEL);
  }
  const flatbuffers::Vector<uint8_t> *embedding_model() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_EMBEDDING_MODEL);
  }
  const RegexModelOptions *regex_options() const {
    return GetPointer<const RegexModelOptions *>(VT_REGEX_OPTIONS);
  }
  const SelectionModelOptions *selection_options() const {
    return GetPointer<const SelectionModelOptions *>(VT_SELECTION_OPTIONS);
  }
  const ClassificationModelOptions *classification_options() const {
    return GetPointer<const ClassificationModelOptions *>(VT_CLASSIFICATION_OPTIONS);
  }
  const StructuredRegexModel *regex_model() const {
    return GetPointer<const StructuredRegexModel *>(VT_REGEX_MODEL);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_LANGUAGE) &&
           verifier.Verify(language()) &&
           VerifyField<int32_t>(verifier, VT_VERSION) &&
           VerifyOffset(verifier, VT_SELECTION_FEATURE_OPTIONS) &&
           verifier.VerifyTable(selection_feature_options()) &&
           VerifyOffset(verifier, VT_CLASSIFICATION_FEATURE_OPTIONS) &&
           verifier.VerifyTable(classification_feature_options()) &&
           VerifyOffset(verifier, VT_SELECTION_MODEL) &&
           verifier.Verify(selection_model()) &&
           VerifyOffset(verifier, VT_CLASSIFICATION_MODEL) &&
           verifier.Verify(classification_model()) &&
           VerifyOffset(verifier, VT_EMBEDDING_MODEL) &&
           verifier.Verify(embedding_model()) &&
           VerifyOffset(verifier, VT_REGEX_OPTIONS) &&
           verifier.VerifyTable(regex_options()) &&
           VerifyOffset(verifier, VT_SELECTION_OPTIONS) &&
           verifier.VerifyTable(selection_options()) &&
           VerifyOffset(verifier, VT_CLASSIFICATION_OPTIONS) &&
           verifier.VerifyTable(classification_options()) &&
           VerifyOffset(verifier, VT_REGEX_MODEL) &&
           verifier.VerifyTable(regex_model()) &&
           verifier.EndTable();
  }
  ModelT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(ModelT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<Model> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ModelT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct ModelBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_language(flatbuffers::Offset<flatbuffers::String> language) {
    fbb_.AddOffset(Model::VT_LANGUAGE, language);
  }
  void add_version(int32_t version) {
    fbb_.AddElement<int32_t>(Model::VT_VERSION, version, 0);
  }
  void add_selection_feature_options(flatbuffers::Offset<FeatureProcessorOptions> selection_feature_options) {
    fbb_.AddOffset(Model::VT_SELECTION_FEATURE_OPTIONS, selection_feature_options);
  }
  void add_classification_feature_options(flatbuffers::Offset<FeatureProcessorOptions> classification_feature_options) {
    fbb_.AddOffset(Model::VT_CLASSIFICATION_FEATURE_OPTIONS, classification_feature_options);
  }
  void add_selection_model(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> selection_model) {
    fbb_.AddOffset(Model::VT_SELECTION_MODEL, selection_model);
  }
  void add_classification_model(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> classification_model) {
    fbb_.AddOffset(Model::VT_CLASSIFICATION_MODEL, classification_model);
  }
  void add_embedding_model(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> embedding_model) {
    fbb_.AddOffset(Model::VT_EMBEDDING_MODEL, embedding_model);
  }
  void add_regex_options(flatbuffers::Offset<RegexModelOptions> regex_options) {
    fbb_.AddOffset(Model::VT_REGEX_OPTIONS, regex_options);
  }
  void add_selection_options(flatbuffers::Offset<SelectionModelOptions> selection_options) {
    fbb_.AddOffset(Model::VT_SELECTION_OPTIONS, selection_options);
  }
  void add_classification_options(flatbuffers::Offset<ClassificationModelOptions> classification_options) {
    fbb_.AddOffset(Model::VT_CLASSIFICATION_OPTIONS, classification_options);
  }
  void add_regex_model(flatbuffers::Offset<StructuredRegexModel> regex_model) {
    fbb_.AddOffset(Model::VT_REGEX_MODEL, regex_model);
  }
  explicit ModelBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ModelBuilder &operator=(const ModelBuilder &);
  flatbuffers::Offset<Model> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Model>(end);
    return o;
  }
};

inline flatbuffers::Offset<Model> CreateModel(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> language = 0,
    int32_t version = 0,
    flatbuffers::Offset<FeatureProcessorOptions> selection_feature_options = 0,
    flatbuffers::Offset<FeatureProcessorOptions> classification_feature_options = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> selection_model = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> classification_model = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> embedding_model = 0,
    flatbuffers::Offset<RegexModelOptions> regex_options = 0,
    flatbuffers::Offset<SelectionModelOptions> selection_options = 0,
    flatbuffers::Offset<ClassificationModelOptions> classification_options = 0,
    flatbuffers::Offset<StructuredRegexModel> regex_model = 0) {
  ModelBuilder builder_(_fbb);
  builder_.add_regex_model(regex_model);
  builder_.add_classification_options(classification_options);
  builder_.add_selection_options(selection_options);
  builder_.add_regex_options(regex_options);
  builder_.add_embedding_model(embedding_model);
  builder_.add_classification_model(classification_model);
  builder_.add_selection_model(selection_model);
  builder_.add_classification_feature_options(classification_feature_options);
  builder_.add_selection_feature_options(selection_feature_options);
  builder_.add_version(version);
  builder_.add_language(language);
  return builder_.Finish();
}

inline flatbuffers::Offset<Model> CreateModelDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *language = nullptr,
    int32_t version = 0,
    flatbuffers::Offset<FeatureProcessorOptions> selection_feature_options = 0,
    flatbuffers::Offset<FeatureProcessorOptions> classification_feature_options = 0,
    const std::vector<uint8_t> *selection_model = nullptr,
    const std::vector<uint8_t> *classification_model = nullptr,
    const std::vector<uint8_t> *embedding_model = nullptr,
    flatbuffers::Offset<RegexModelOptions> regex_options = 0,
    flatbuffers::Offset<SelectionModelOptions> selection_options = 0,
    flatbuffers::Offset<ClassificationModelOptions> classification_options = 0,
    flatbuffers::Offset<StructuredRegexModel> regex_model = 0) {
  return libtextclassifier2::CreateModel(
      _fbb,
      language ? _fbb.CreateString(language) : 0,
      version,
      selection_feature_options,
      classification_feature_options,
      selection_model ? _fbb.CreateVector<uint8_t>(*selection_model) : 0,
      classification_model ? _fbb.CreateVector<uint8_t>(*classification_model) : 0,
      embedding_model ? _fbb.CreateVector<uint8_t>(*embedding_model) : 0,
      regex_options,
      selection_options,
      classification_options,
      regex_model);
}

flatbuffers::Offset<Model> CreateModel(flatbuffers::FlatBufferBuilder &_fbb, const ModelT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct TokenizationCodepointRangeT : public flatbuffers::NativeTable {
  typedef TokenizationCodepointRange TableType;
  int32_t start;
  int32_t end;
  libtextclassifier2::TokenizationCodepointRange_::Role role;
  int32_t script_id;
  TokenizationCodepointRangeT()
      : start(0),
        end(0),
        role(libtextclassifier2::TokenizationCodepointRange_::Role_DEFAULT_ROLE),
        script_id(0) {
  }
};

struct TokenizationCodepointRange FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef TokenizationCodepointRangeT NativeTableType;
  enum {
    VT_START = 4,
    VT_END = 6,
    VT_ROLE = 8,
    VT_SCRIPT_ID = 10
  };
  int32_t start() const {
    return GetField<int32_t>(VT_START, 0);
  }
  int32_t end() const {
    return GetField<int32_t>(VT_END, 0);
  }
  libtextclassifier2::TokenizationCodepointRange_::Role role() const {
    return static_cast<libtextclassifier2::TokenizationCodepointRange_::Role>(GetField<int32_t>(VT_ROLE, 0));
  }
  int32_t script_id() const {
    return GetField<int32_t>(VT_SCRIPT_ID, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_START) &&
           VerifyField<int32_t>(verifier, VT_END) &&
           VerifyField<int32_t>(verifier, VT_ROLE) &&
           VerifyField<int32_t>(verifier, VT_SCRIPT_ID) &&
           verifier.EndTable();
  }
  TokenizationCodepointRangeT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(TokenizationCodepointRangeT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<TokenizationCodepointRange> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TokenizationCodepointRangeT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct TokenizationCodepointRangeBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_start(int32_t start) {
    fbb_.AddElement<int32_t>(TokenizationCodepointRange::VT_START, start, 0);
  }
  void add_end(int32_t end) {
    fbb_.AddElement<int32_t>(TokenizationCodepointRange::VT_END, end, 0);
  }
  void add_role(libtextclassifier2::TokenizationCodepointRange_::Role role) {
    fbb_.AddElement<int32_t>(TokenizationCodepointRange::VT_ROLE, static_cast<int32_t>(role), 0);
  }
  void add_script_id(int32_t script_id) {
    fbb_.AddElement<int32_t>(TokenizationCodepointRange::VT_SCRIPT_ID, script_id, 0);
  }
  explicit TokenizationCodepointRangeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TokenizationCodepointRangeBuilder &operator=(const TokenizationCodepointRangeBuilder &);
  flatbuffers::Offset<TokenizationCodepointRange> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TokenizationCodepointRange>(end);
    return o;
  }
};

inline flatbuffers::Offset<TokenizationCodepointRange> CreateTokenizationCodepointRange(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t start = 0,
    int32_t end = 0,
    libtextclassifier2::TokenizationCodepointRange_::Role role = libtextclassifier2::TokenizationCodepointRange_::Role_DEFAULT_ROLE,
    int32_t script_id = 0) {
  TokenizationCodepointRangeBuilder builder_(_fbb);
  builder_.add_script_id(script_id);
  builder_.add_role(role);
  builder_.add_end(end);
  builder_.add_start(start);
  return builder_.Finish();
}

flatbuffers::Offset<TokenizationCodepointRange> CreateTokenizationCodepointRange(flatbuffers::FlatBufferBuilder &_fbb, const TokenizationCodepointRangeT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct FeatureProcessorOptionsT : public flatbuffers::NativeTable {
  typedef FeatureProcessorOptions TableType;
  int32_t num_buckets;
  int32_t embedding_size;
  int32_t context_size;
  int32_t max_selection_span;
  std::vector<int32_t> chargram_orders;
  int32_t max_word_length;
  bool unicode_aware_features;
  bool extract_case_feature;
  bool extract_selection_mask_feature;
  std::vector<std::string> regexp_feature;
  bool remap_digits;
  bool lowercase_tokens;
  bool selection_reduced_output_space;
  std::vector<std::string> collections;
  int32_t default_collection;
  bool only_use_line_with_click;
  bool split_tokens_on_selection_boundaries;
  std::vector<std::unique_ptr<TokenizationCodepointRangeT>> tokenization_codepoint_config;
  libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod center_token_selection_method;
  bool snap_label_span_boundaries_to_containing_tokens;
  std::vector<std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::CodepointRangeT>> supported_codepoint_ranges;
  std::vector<std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::CodepointRangeT>> internal_tokenizer_codepoint_ranges;
  float min_supported_codepoint_ratio;
  int32_t feature_version;
  libtextclassifier2::FeatureProcessorOptions_::TokenizationType tokenization_type;
  bool icu_preserve_whitespace_tokens;
  std::vector<int32_t> ignored_span_boundary_codepoints;
  bool click_random_token_in_selection;
  std::vector<std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntryT>> alternative_collection_map;
  std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeaturesT> bounds_sensitive_features;
  bool split_selection_candidates;
  std::vector<std::string> allowed_chargrams;
  bool tokenize_on_script_change;
  FeatureProcessorOptionsT()
      : num_buckets(-1),
        embedding_size(-1),
        context_size(-1),
        max_selection_span(-1),
        max_word_length(20),
        unicode_aware_features(false),
        extract_case_feature(false),
        extract_selection_mask_feature(false),
        remap_digits(false),
        lowercase_tokens(false),
        selection_reduced_output_space(false),
        default_collection(-1),
        only_use_line_with_click(false),
        split_tokens_on_selection_boundaries(false),
        center_token_selection_method(libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod_DEFAULT_CENTER_TOKEN_METHOD),
        snap_label_span_boundaries_to_containing_tokens(false),
        min_supported_codepoint_ratio(0.0f),
        feature_version(0),
        tokenization_type(libtextclassifier2::FeatureProcessorOptions_::TokenizationType_INVALID_TOKENIZATION_TYPE),
        icu_preserve_whitespace_tokens(false),
        click_random_token_in_selection(false),
        split_selection_candidates(false),
        tokenize_on_script_change(false) {
  }
};

struct FeatureProcessorOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FeatureProcessorOptionsT NativeTableType;
  enum {
    VT_NUM_BUCKETS = 4,
    VT_EMBEDDING_SIZE = 6,
    VT_CONTEXT_SIZE = 8,
    VT_MAX_SELECTION_SPAN = 10,
    VT_CHARGRAM_ORDERS = 12,
    VT_MAX_WORD_LENGTH = 14,
    VT_UNICODE_AWARE_FEATURES = 16,
    VT_EXTRACT_CASE_FEATURE = 18,
    VT_EXTRACT_SELECTION_MASK_FEATURE = 20,
    VT_REGEXP_FEATURE = 22,
    VT_REMAP_DIGITS = 24,
    VT_LOWERCASE_TOKENS = 26,
    VT_SELECTION_REDUCED_OUTPUT_SPACE = 28,
    VT_COLLECTIONS = 30,
    VT_DEFAULT_COLLECTION = 32,
    VT_ONLY_USE_LINE_WITH_CLICK = 34,
    VT_SPLIT_TOKENS_ON_SELECTION_BOUNDARIES = 36,
    VT_TOKENIZATION_CODEPOINT_CONFIG = 38,
    VT_CENTER_TOKEN_SELECTION_METHOD = 40,
    VT_SNAP_LABEL_SPAN_BOUNDARIES_TO_CONTAINING_TOKENS = 42,
    VT_SUPPORTED_CODEPOINT_RANGES = 44,
    VT_INTERNAL_TOKENIZER_CODEPOINT_RANGES = 46,
    VT_MIN_SUPPORTED_CODEPOINT_RATIO = 48,
    VT_FEATURE_VERSION = 50,
    VT_TOKENIZATION_TYPE = 52,
    VT_ICU_PRESERVE_WHITESPACE_TOKENS = 54,
    VT_IGNORED_SPAN_BOUNDARY_CODEPOINTS = 56,
    VT_CLICK_RANDOM_TOKEN_IN_SELECTION = 58,
    VT_ALTERNATIVE_COLLECTION_MAP = 60,
    VT_BOUNDS_SENSITIVE_FEATURES = 62,
    VT_SPLIT_SELECTION_CANDIDATES = 64,
    VT_ALLOWED_CHARGRAMS = 66,
    VT_TOKENIZE_ON_SCRIPT_CHANGE = 68
  };
  int32_t num_buckets() const {
    return GetField<int32_t>(VT_NUM_BUCKETS, -1);
  }
  int32_t embedding_size() const {
    return GetField<int32_t>(VT_EMBEDDING_SIZE, -1);
  }
  int32_t context_size() const {
    return GetField<int32_t>(VT_CONTEXT_SIZE, -1);
  }
  int32_t max_selection_span() const {
    return GetField<int32_t>(VT_MAX_SELECTION_SPAN, -1);
  }
  const flatbuffers::Vector<int32_t> *chargram_orders() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_CHARGRAM_ORDERS);
  }
  int32_t max_word_length() const {
    return GetField<int32_t>(VT_MAX_WORD_LENGTH, 20);
  }
  bool unicode_aware_features() const {
    return GetField<uint8_t>(VT_UNICODE_AWARE_FEATURES, 0) != 0;
  }
  bool extract_case_feature() const {
    return GetField<uint8_t>(VT_EXTRACT_CASE_FEATURE, 0) != 0;
  }
  bool extract_selection_mask_feature() const {
    return GetField<uint8_t>(VT_EXTRACT_SELECTION_MASK_FEATURE, 0) != 0;
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *regexp_feature() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_REGEXP_FEATURE);
  }
  bool remap_digits() const {
    return GetField<uint8_t>(VT_REMAP_DIGITS, 0) != 0;
  }
  bool lowercase_tokens() const {
    return GetField<uint8_t>(VT_LOWERCASE_TOKENS, 0) != 0;
  }
  bool selection_reduced_output_space() const {
    return GetField<uint8_t>(VT_SELECTION_REDUCED_OUTPUT_SPACE, 0) != 0;
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *collections() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_COLLECTIONS);
  }
  int32_t default_collection() const {
    return GetField<int32_t>(VT_DEFAULT_COLLECTION, -1);
  }
  bool only_use_line_with_click() const {
    return GetField<uint8_t>(VT_ONLY_USE_LINE_WITH_CLICK, 0) != 0;
  }
  bool split_tokens_on_selection_boundaries() const {
    return GetField<uint8_t>(VT_SPLIT_TOKENS_ON_SELECTION_BOUNDARIES, 0) != 0;
  }
  const flatbuffers::Vector<flatbuffers::Offset<TokenizationCodepointRange>> *tokenization_codepoint_config() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<TokenizationCodepointRange>> *>(VT_TOKENIZATION_CODEPOINT_CONFIG);
  }
  libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod center_token_selection_method() const {
    return static_cast<libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod>(GetField<int32_t>(VT_CENTER_TOKEN_SELECTION_METHOD, 0));
  }
  bool snap_label_span_boundaries_to_containing_tokens() const {
    return GetField<uint8_t>(VT_SNAP_LABEL_SPAN_BOUNDARIES_TO_CONTAINING_TOKENS, 0) != 0;
  }
  const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> *supported_codepoint_ranges() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> *>(VT_SUPPORTED_CODEPOINT_RANGES);
  }
  const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> *internal_tokenizer_codepoint_ranges() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> *>(VT_INTERNAL_TOKENIZER_CODEPOINT_RANGES);
  }
  float min_supported_codepoint_ratio() const {
    return GetField<float>(VT_MIN_SUPPORTED_CODEPOINT_RATIO, 0.0f);
  }
  int32_t feature_version() const {
    return GetField<int32_t>(VT_FEATURE_VERSION, 0);
  }
  libtextclassifier2::FeatureProcessorOptions_::TokenizationType tokenization_type() const {
    return static_cast<libtextclassifier2::FeatureProcessorOptions_::TokenizationType>(GetField<int32_t>(VT_TOKENIZATION_TYPE, 0));
  }
  bool icu_preserve_whitespace_tokens() const {
    return GetField<uint8_t>(VT_ICU_PRESERVE_WHITESPACE_TOKENS, 0) != 0;
  }
  const flatbuffers::Vector<int32_t> *ignored_span_boundary_codepoints() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_IGNORED_SPAN_BOUNDARY_CODEPOINTS);
  }
  bool click_random_token_in_selection() const {
    return GetField<uint8_t>(VT_CLICK_RANDOM_TOKEN_IN_SELECTION, 0) != 0;
  }
  const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntry>> *alternative_collection_map() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntry>> *>(VT_ALTERNATIVE_COLLECTION_MAP);
  }
  const libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures *bounds_sensitive_features() const {
    return GetPointer<const libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures *>(VT_BOUNDS_SENSITIVE_FEATURES);
  }
  bool split_selection_candidates() const {
    return GetField<uint8_t>(VT_SPLIT_SELECTION_CANDIDATES, 0) != 0;
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *allowed_chargrams() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_ALLOWED_CHARGRAMS);
  }
  bool tokenize_on_script_change() const {
    return GetField<uint8_t>(VT_TOKENIZE_ON_SCRIPT_CHANGE, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_NUM_BUCKETS) &&
           VerifyField<int32_t>(verifier, VT_EMBEDDING_SIZE) &&
           VerifyField<int32_t>(verifier, VT_CONTEXT_SIZE) &&
           VerifyField<int32_t>(verifier, VT_MAX_SELECTION_SPAN) &&
           VerifyOffset(verifier, VT_CHARGRAM_ORDERS) &&
           verifier.Verify(chargram_orders()) &&
           VerifyField<int32_t>(verifier, VT_MAX_WORD_LENGTH) &&
           VerifyField<uint8_t>(verifier, VT_UNICODE_AWARE_FEATURES) &&
           VerifyField<uint8_t>(verifier, VT_EXTRACT_CASE_FEATURE) &&
           VerifyField<uint8_t>(verifier, VT_EXTRACT_SELECTION_MASK_FEATURE) &&
           VerifyOffset(verifier, VT_REGEXP_FEATURE) &&
           verifier.Verify(regexp_feature()) &&
           verifier.VerifyVectorOfStrings(regexp_feature()) &&
           VerifyField<uint8_t>(verifier, VT_REMAP_DIGITS) &&
           VerifyField<uint8_t>(verifier, VT_LOWERCASE_TOKENS) &&
           VerifyField<uint8_t>(verifier, VT_SELECTION_REDUCED_OUTPUT_SPACE) &&
           VerifyOffset(verifier, VT_COLLECTIONS) &&
           verifier.Verify(collections()) &&
           verifier.VerifyVectorOfStrings(collections()) &&
           VerifyField<int32_t>(verifier, VT_DEFAULT_COLLECTION) &&
           VerifyField<uint8_t>(verifier, VT_ONLY_USE_LINE_WITH_CLICK) &&
           VerifyField<uint8_t>(verifier, VT_SPLIT_TOKENS_ON_SELECTION_BOUNDARIES) &&
           VerifyOffset(verifier, VT_TOKENIZATION_CODEPOINT_CONFIG) &&
           verifier.Verify(tokenization_codepoint_config()) &&
           verifier.VerifyVectorOfTables(tokenization_codepoint_config()) &&
           VerifyField<int32_t>(verifier, VT_CENTER_TOKEN_SELECTION_METHOD) &&
           VerifyField<uint8_t>(verifier, VT_SNAP_LABEL_SPAN_BOUNDARIES_TO_CONTAINING_TOKENS) &&
           VerifyOffset(verifier, VT_SUPPORTED_CODEPOINT_RANGES) &&
           verifier.Verify(supported_codepoint_ranges()) &&
           verifier.VerifyVectorOfTables(supported_codepoint_ranges()) &&
           VerifyOffset(verifier, VT_INTERNAL_TOKENIZER_CODEPOINT_RANGES) &&
           verifier.Verify(internal_tokenizer_codepoint_ranges()) &&
           verifier.VerifyVectorOfTables(internal_tokenizer_codepoint_ranges()) &&
           VerifyField<float>(verifier, VT_MIN_SUPPORTED_CODEPOINT_RATIO) &&
           VerifyField<int32_t>(verifier, VT_FEATURE_VERSION) &&
           VerifyField<int32_t>(verifier, VT_TOKENIZATION_TYPE) &&
           VerifyField<uint8_t>(verifier, VT_ICU_PRESERVE_WHITESPACE_TOKENS) &&
           VerifyOffset(verifier, VT_IGNORED_SPAN_BOUNDARY_CODEPOINTS) &&
           verifier.Verify(ignored_span_boundary_codepoints()) &&
           VerifyField<uint8_t>(verifier, VT_CLICK_RANDOM_TOKEN_IN_SELECTION) &&
           VerifyOffset(verifier, VT_ALTERNATIVE_COLLECTION_MAP) &&
           verifier.Verify(alternative_collection_map()) &&
           verifier.VerifyVectorOfTables(alternative_collection_map()) &&
           VerifyOffset(verifier, VT_BOUNDS_SENSITIVE_FEATURES) &&
           verifier.VerifyTable(bounds_sensitive_features()) &&
           VerifyField<uint8_t>(verifier, VT_SPLIT_SELECTION_CANDIDATES) &&
           VerifyOffset(verifier, VT_ALLOWED_CHARGRAMS) &&
           verifier.Verify(allowed_chargrams()) &&
           verifier.VerifyVectorOfStrings(allowed_chargrams()) &&
           VerifyField<uint8_t>(verifier, VT_TOKENIZE_ON_SCRIPT_CHANGE) &&
           verifier.EndTable();
  }
  FeatureProcessorOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(FeatureProcessorOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<FeatureProcessorOptions> Pack(flatbuffers::FlatBufferBuilder &_fbb, const FeatureProcessorOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct FeatureProcessorOptionsBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_num_buckets(int32_t num_buckets) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_NUM_BUCKETS, num_buckets, -1);
  }
  void add_embedding_size(int32_t embedding_size) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_EMBEDDING_SIZE, embedding_size, -1);
  }
  void add_context_size(int32_t context_size) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_CONTEXT_SIZE, context_size, -1);
  }
  void add_max_selection_span(int32_t max_selection_span) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_MAX_SELECTION_SPAN, max_selection_span, -1);
  }
  void add_chargram_orders(flatbuffers::Offset<flatbuffers::Vector<int32_t>> chargram_orders) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_CHARGRAM_ORDERS, chargram_orders);
  }
  void add_max_word_length(int32_t max_word_length) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_MAX_WORD_LENGTH, max_word_length, 20);
  }
  void add_unicode_aware_features(bool unicode_aware_features) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_UNICODE_AWARE_FEATURES, static_cast<uint8_t>(unicode_aware_features), 0);
  }
  void add_extract_case_feature(bool extract_case_feature) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_EXTRACT_CASE_FEATURE, static_cast<uint8_t>(extract_case_feature), 0);
  }
  void add_extract_selection_mask_feature(bool extract_selection_mask_feature) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_EXTRACT_SELECTION_MASK_FEATURE, static_cast<uint8_t>(extract_selection_mask_feature), 0);
  }
  void add_regexp_feature(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> regexp_feature) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_REGEXP_FEATURE, regexp_feature);
  }
  void add_remap_digits(bool remap_digits) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_REMAP_DIGITS, static_cast<uint8_t>(remap_digits), 0);
  }
  void add_lowercase_tokens(bool lowercase_tokens) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_LOWERCASE_TOKENS, static_cast<uint8_t>(lowercase_tokens), 0);
  }
  void add_selection_reduced_output_space(bool selection_reduced_output_space) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_SELECTION_REDUCED_OUTPUT_SPACE, static_cast<uint8_t>(selection_reduced_output_space), 0);
  }
  void add_collections(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> collections) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_COLLECTIONS, collections);
  }
  void add_default_collection(int32_t default_collection) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_DEFAULT_COLLECTION, default_collection, -1);
  }
  void add_only_use_line_with_click(bool only_use_line_with_click) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_ONLY_USE_LINE_WITH_CLICK, static_cast<uint8_t>(only_use_line_with_click), 0);
  }
  void add_split_tokens_on_selection_boundaries(bool split_tokens_on_selection_boundaries) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_SPLIT_TOKENS_ON_SELECTION_BOUNDARIES, static_cast<uint8_t>(split_tokens_on_selection_boundaries), 0);
  }
  void add_tokenization_codepoint_config(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TokenizationCodepointRange>>> tokenization_codepoint_config) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_TOKENIZATION_CODEPOINT_CONFIG, tokenization_codepoint_config);
  }
  void add_center_token_selection_method(libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod center_token_selection_method) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_CENTER_TOKEN_SELECTION_METHOD, static_cast<int32_t>(center_token_selection_method), 0);
  }
  void add_snap_label_span_boundaries_to_containing_tokens(bool snap_label_span_boundaries_to_containing_tokens) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_SNAP_LABEL_SPAN_BOUNDARIES_TO_CONTAINING_TOKENS, static_cast<uint8_t>(snap_label_span_boundaries_to_containing_tokens), 0);
  }
  void add_supported_codepoint_ranges(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>>> supported_codepoint_ranges) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_SUPPORTED_CODEPOINT_RANGES, supported_codepoint_ranges);
  }
  void add_internal_tokenizer_codepoint_ranges(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>>> internal_tokenizer_codepoint_ranges) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_INTERNAL_TOKENIZER_CODEPOINT_RANGES, internal_tokenizer_codepoint_ranges);
  }
  void add_min_supported_codepoint_ratio(float min_supported_codepoint_ratio) {
    fbb_.AddElement<float>(FeatureProcessorOptions::VT_MIN_SUPPORTED_CODEPOINT_RATIO, min_supported_codepoint_ratio, 0.0f);
  }
  void add_feature_version(int32_t feature_version) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_FEATURE_VERSION, feature_version, 0);
  }
  void add_tokenization_type(libtextclassifier2::FeatureProcessorOptions_::TokenizationType tokenization_type) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_TOKENIZATION_TYPE, static_cast<int32_t>(tokenization_type), 0);
  }
  void add_icu_preserve_whitespace_tokens(bool icu_preserve_whitespace_tokens) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_ICU_PRESERVE_WHITESPACE_TOKENS, static_cast<uint8_t>(icu_preserve_whitespace_tokens), 0);
  }
  void add_ignored_span_boundary_codepoints(flatbuffers::Offset<flatbuffers::Vector<int32_t>> ignored_span_boundary_codepoints) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_IGNORED_SPAN_BOUNDARY_CODEPOINTS, ignored_span_boundary_codepoints);
  }
  void add_click_random_token_in_selection(bool click_random_token_in_selection) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_CLICK_RANDOM_TOKEN_IN_SELECTION, static_cast<uint8_t>(click_random_token_in_selection), 0);
  }
  void add_alternative_collection_map(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntry>>> alternative_collection_map) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_ALTERNATIVE_COLLECTION_MAP, alternative_collection_map);
  }
  void add_bounds_sensitive_features(flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures> bounds_sensitive_features) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_BOUNDS_SENSITIVE_FEATURES, bounds_sensitive_features);
  }
  void add_split_selection_candidates(bool split_selection_candidates) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_SPLIT_SELECTION_CANDIDATES, static_cast<uint8_t>(split_selection_candidates), 0);
  }
  void add_allowed_chargrams(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> allowed_chargrams) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_ALLOWED_CHARGRAMS, allowed_chargrams);
  }
  void add_tokenize_on_script_change(bool tokenize_on_script_change) {
    fbb_.AddElement<uint8_t>(FeatureProcessorOptions::VT_TOKENIZE_ON_SCRIPT_CHANGE, static_cast<uint8_t>(tokenize_on_script_change), 0);
  }
  explicit FeatureProcessorOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FeatureProcessorOptionsBuilder &operator=(const FeatureProcessorOptionsBuilder &);
  flatbuffers::Offset<FeatureProcessorOptions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FeatureProcessorOptions>(end);
    return o;
  }
};

inline flatbuffers::Offset<FeatureProcessorOptions> CreateFeatureProcessorOptions(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t num_buckets = -1,
    int32_t embedding_size = -1,
    int32_t context_size = -1,
    int32_t max_selection_span = -1,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> chargram_orders = 0,
    int32_t max_word_length = 20,
    bool unicode_aware_features = false,
    bool extract_case_feature = false,
    bool extract_selection_mask_feature = false,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> regexp_feature = 0,
    bool remap_digits = false,
    bool lowercase_tokens = false,
    bool selection_reduced_output_space = false,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> collections = 0,
    int32_t default_collection = -1,
    bool only_use_line_with_click = false,
    bool split_tokens_on_selection_boundaries = false,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TokenizationCodepointRange>>> tokenization_codepoint_config = 0,
    libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod center_token_selection_method = libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod_DEFAULT_CENTER_TOKEN_METHOD,
    bool snap_label_span_boundaries_to_containing_tokens = false,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>>> supported_codepoint_ranges = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>>> internal_tokenizer_codepoint_ranges = 0,
    float min_supported_codepoint_ratio = 0.0f,
    int32_t feature_version = 0,
    libtextclassifier2::FeatureProcessorOptions_::TokenizationType tokenization_type = libtextclassifier2::FeatureProcessorOptions_::TokenizationType_INVALID_TOKENIZATION_TYPE,
    bool icu_preserve_whitespace_tokens = false,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> ignored_span_boundary_codepoints = 0,
    bool click_random_token_in_selection = false,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntry>>> alternative_collection_map = 0,
    flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures> bounds_sensitive_features = 0,
    bool split_selection_candidates = false,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> allowed_chargrams = 0,
    bool tokenize_on_script_change = false) {
  FeatureProcessorOptionsBuilder builder_(_fbb);
  builder_.add_allowed_chargrams(allowed_chargrams);
  builder_.add_bounds_sensitive_features(bounds_sensitive_features);
  builder_.add_alternative_collection_map(alternative_collection_map);
  builder_.add_ignored_span_boundary_codepoints(ignored_span_boundary_codepoints);
  builder_.add_tokenization_type(tokenization_type);
  builder_.add_feature_version(feature_version);
  builder_.add_min_supported_codepoint_ratio(min_supported_codepoint_ratio);
  builder_.add_internal_tokenizer_codepoint_ranges(internal_tokenizer_codepoint_ranges);
  builder_.add_supported_codepoint_ranges(supported_codepoint_ranges);
  builder_.add_center_token_selection_method(center_token_selection_method);
  builder_.add_tokenization_codepoint_config(tokenization_codepoint_config);
  builder_.add_default_collection(default_collection);
  builder_.add_collections(collections);
  builder_.add_regexp_feature(regexp_feature);
  builder_.add_max_word_length(max_word_length);
  builder_.add_chargram_orders(chargram_orders);
  builder_.add_max_selection_span(max_selection_span);
  builder_.add_context_size(context_size);
  builder_.add_embedding_size(embedding_size);
  builder_.add_num_buckets(num_buckets);
  builder_.add_tokenize_on_script_change(tokenize_on_script_change);
  builder_.add_split_selection_candidates(split_selection_candidates);
  builder_.add_click_random_token_in_selection(click_random_token_in_selection);
  builder_.add_icu_preserve_whitespace_tokens(icu_preserve_whitespace_tokens);
  builder_.add_snap_label_span_boundaries_to_containing_tokens(snap_label_span_boundaries_to_containing_tokens);
  builder_.add_split_tokens_on_selection_boundaries(split_tokens_on_selection_boundaries);
  builder_.add_only_use_line_with_click(only_use_line_with_click);
  builder_.add_selection_reduced_output_space(selection_reduced_output_space);
  builder_.add_lowercase_tokens(lowercase_tokens);
  builder_.add_remap_digits(remap_digits);
  builder_.add_extract_selection_mask_feature(extract_selection_mask_feature);
  builder_.add_extract_case_feature(extract_case_feature);
  builder_.add_unicode_aware_features(unicode_aware_features);
  return builder_.Finish();
}

inline flatbuffers::Offset<FeatureProcessorOptions> CreateFeatureProcessorOptionsDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t num_buckets = -1,
    int32_t embedding_size = -1,
    int32_t context_size = -1,
    int32_t max_selection_span = -1,
    const std::vector<int32_t> *chargram_orders = nullptr,
    int32_t max_word_length = 20,
    bool unicode_aware_features = false,
    bool extract_case_feature = false,
    bool extract_selection_mask_feature = false,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *regexp_feature = nullptr,
    bool remap_digits = false,
    bool lowercase_tokens = false,
    bool selection_reduced_output_space = false,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *collections = nullptr,
    int32_t default_collection = -1,
    bool only_use_line_with_click = false,
    bool split_tokens_on_selection_boundaries = false,
    const std::vector<flatbuffers::Offset<TokenizationCodepointRange>> *tokenization_codepoint_config = nullptr,
    libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod center_token_selection_method = libtextclassifier2::FeatureProcessorOptions_::CenterTokenSelectionMethod_DEFAULT_CENTER_TOKEN_METHOD,
    bool snap_label_span_boundaries_to_containing_tokens = false,
    const std::vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> *supported_codepoint_ranges = nullptr,
    const std::vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> *internal_tokenizer_codepoint_ranges = nullptr,
    float min_supported_codepoint_ratio = 0.0f,
    int32_t feature_version = 0,
    libtextclassifier2::FeatureProcessorOptions_::TokenizationType tokenization_type = libtextclassifier2::FeatureProcessorOptions_::TokenizationType_INVALID_TOKENIZATION_TYPE,
    bool icu_preserve_whitespace_tokens = false,
    const std::vector<int32_t> *ignored_span_boundary_codepoints = nullptr,
    bool click_random_token_in_selection = false,
    const std::vector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntry>> *alternative_collection_map = nullptr,
    flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures> bounds_sensitive_features = 0,
    bool split_selection_candidates = false,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *allowed_chargrams = nullptr,
    bool tokenize_on_script_change = false) {
  return libtextclassifier2::CreateFeatureProcessorOptions(
      _fbb,
      num_buckets,
      embedding_size,
      context_size,
      max_selection_span,
      chargram_orders ? _fbb.CreateVector<int32_t>(*chargram_orders) : 0,
      max_word_length,
      unicode_aware_features,
      extract_case_feature,
      extract_selection_mask_feature,
      regexp_feature ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*regexp_feature) : 0,
      remap_digits,
      lowercase_tokens,
      selection_reduced_output_space,
      collections ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*collections) : 0,
      default_collection,
      only_use_line_with_click,
      split_tokens_on_selection_boundaries,
      tokenization_codepoint_config ? _fbb.CreateVector<flatbuffers::Offset<TokenizationCodepointRange>>(*tokenization_codepoint_config) : 0,
      center_token_selection_method,
      snap_label_span_boundaries_to_containing_tokens,
      supported_codepoint_ranges ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>>(*supported_codepoint_ranges) : 0,
      internal_tokenizer_codepoint_ranges ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>>(*internal_tokenizer_codepoint_ranges) : 0,
      min_supported_codepoint_ratio,
      feature_version,
      tokenization_type,
      icu_preserve_whitespace_tokens,
      ignored_span_boundary_codepoints ? _fbb.CreateVector<int32_t>(*ignored_span_boundary_codepoints) : 0,
      click_random_token_in_selection,
      alternative_collection_map ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntry>>(*alternative_collection_map) : 0,
      bounds_sensitive_features,
      split_selection_candidates,
      allowed_chargrams ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*allowed_chargrams) : 0,
      tokenize_on_script_change);
}

flatbuffers::Offset<FeatureProcessorOptions> CreateFeatureProcessorOptions(flatbuffers::FlatBufferBuilder &_fbb, const FeatureProcessorOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

namespace FeatureProcessorOptions_ {

struct CodepointRangeT : public flatbuffers::NativeTable {
  typedef CodepointRange TableType;
  int32_t start;
  int32_t end;
  CodepointRangeT()
      : start(0),
        end(0) {
  }
};

struct CodepointRange FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef CodepointRangeT NativeTableType;
  enum {
    VT_START = 4,
    VT_END = 6
  };
  int32_t start() const {
    return GetField<int32_t>(VT_START, 0);
  }
  int32_t end() const {
    return GetField<int32_t>(VT_END, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_START) &&
           VerifyField<int32_t>(verifier, VT_END) &&
           verifier.EndTable();
  }
  CodepointRangeT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(CodepointRangeT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<CodepointRange> Pack(flatbuffers::FlatBufferBuilder &_fbb, const CodepointRangeT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct CodepointRangeBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_start(int32_t start) {
    fbb_.AddElement<int32_t>(CodepointRange::VT_START, start, 0);
  }
  void add_end(int32_t end) {
    fbb_.AddElement<int32_t>(CodepointRange::VT_END, end, 0);
  }
  explicit CodepointRangeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  CodepointRangeBuilder &operator=(const CodepointRangeBuilder &);
  flatbuffers::Offset<CodepointRange> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CodepointRange>(end);
    return o;
  }
};

inline flatbuffers::Offset<CodepointRange> CreateCodepointRange(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t start = 0,
    int32_t end = 0) {
  CodepointRangeBuilder builder_(_fbb);
  builder_.add_end(end);
  builder_.add_start(start);
  return builder_.Finish();
}

flatbuffers::Offset<CodepointRange> CreateCodepointRange(flatbuffers::FlatBufferBuilder &_fbb, const CodepointRangeT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct CollectionMapEntryT : public flatbuffers::NativeTable {
  typedef CollectionMapEntry TableType;
  std::string key;
  std::string value;
  CollectionMapEntryT() {
  }
};

struct CollectionMapEntry FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef CollectionMapEntryT NativeTableType;
  enum {
    VT_KEY = 4,
    VT_VALUE = 6
  };
  const flatbuffers::String *key() const {
    return GetPointer<const flatbuffers::String *>(VT_KEY);
  }
  const flatbuffers::String *value() const {
    return GetPointer<const flatbuffers::String *>(VT_VALUE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_KEY) &&
           verifier.Verify(key()) &&
           VerifyOffset(verifier, VT_VALUE) &&
           verifier.Verify(value()) &&
           verifier.EndTable();
  }
  CollectionMapEntryT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(CollectionMapEntryT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<CollectionMapEntry> Pack(flatbuffers::FlatBufferBuilder &_fbb, const CollectionMapEntryT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct CollectionMapEntryBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_key(flatbuffers::Offset<flatbuffers::String> key) {
    fbb_.AddOffset(CollectionMapEntry::VT_KEY, key);
  }
  void add_value(flatbuffers::Offset<flatbuffers::String> value) {
    fbb_.AddOffset(CollectionMapEntry::VT_VALUE, value);
  }
  explicit CollectionMapEntryBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  CollectionMapEntryBuilder &operator=(const CollectionMapEntryBuilder &);
  flatbuffers::Offset<CollectionMapEntry> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CollectionMapEntry>(end);
    return o;
  }
};

inline flatbuffers::Offset<CollectionMapEntry> CreateCollectionMapEntry(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> key = 0,
    flatbuffers::Offset<flatbuffers::String> value = 0) {
  CollectionMapEntryBuilder builder_(_fbb);
  builder_.add_value(value);
  builder_.add_key(key);
  return builder_.Finish();
}

inline flatbuffers::Offset<CollectionMapEntry> CreateCollectionMapEntryDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *key = nullptr,
    const char *value = nullptr) {
  return libtextclassifier2::FeatureProcessorOptions_::CreateCollectionMapEntry(
      _fbb,
      key ? _fbb.CreateString(key) : 0,
      value ? _fbb.CreateString(value) : 0);
}

flatbuffers::Offset<CollectionMapEntry> CreateCollectionMapEntry(flatbuffers::FlatBufferBuilder &_fbb, const CollectionMapEntryT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct BoundsSensitiveFeaturesT : public flatbuffers::NativeTable {
  typedef BoundsSensitiveFeatures TableType;
  bool enabled;
  int32_t num_tokens_before;
  int32_t num_tokens_inside_left;
  int32_t num_tokens_inside_right;
  int32_t num_tokens_after;
  bool include_inside_bag;
  bool include_inside_length;
  BoundsSensitiveFeaturesT()
      : enabled(false),
        num_tokens_before(0),
        num_tokens_inside_left(0),
        num_tokens_inside_right(0),
        num_tokens_after(0),
        include_inside_bag(false),
        include_inside_length(false) {
  }
};

struct BoundsSensitiveFeatures FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef BoundsSensitiveFeaturesT NativeTableType;
  enum {
    VT_ENABLED = 4,
    VT_NUM_TOKENS_BEFORE = 6,
    VT_NUM_TOKENS_INSIDE_LEFT = 8,
    VT_NUM_TOKENS_INSIDE_RIGHT = 10,
    VT_NUM_TOKENS_AFTER = 12,
    VT_INCLUDE_INSIDE_BAG = 14,
    VT_INCLUDE_INSIDE_LENGTH = 16
  };
  bool enabled() const {
    return GetField<uint8_t>(VT_ENABLED, 0) != 0;
  }
  int32_t num_tokens_before() const {
    return GetField<int32_t>(VT_NUM_TOKENS_BEFORE, 0);
  }
  int32_t num_tokens_inside_left() const {
    return GetField<int32_t>(VT_NUM_TOKENS_INSIDE_LEFT, 0);
  }
  int32_t num_tokens_inside_right() const {
    return GetField<int32_t>(VT_NUM_TOKENS_INSIDE_RIGHT, 0);
  }
  int32_t num_tokens_after() const {
    return GetField<int32_t>(VT_NUM_TOKENS_AFTER, 0);
  }
  bool include_inside_bag() const {
    return GetField<uint8_t>(VT_INCLUDE_INSIDE_BAG, 0) != 0;
  }
  bool include_inside_length() const {
    return GetField<uint8_t>(VT_INCLUDE_INSIDE_LENGTH, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_ENABLED) &&
           VerifyField<int32_t>(verifier, VT_NUM_TOKENS_BEFORE) &&
           VerifyField<int32_t>(verifier, VT_NUM_TOKENS_INSIDE_LEFT) &&
           VerifyField<int32_t>(verifier, VT_NUM_TOKENS_INSIDE_RIGHT) &&
           VerifyField<int32_t>(verifier, VT_NUM_TOKENS_AFTER) &&
           VerifyField<uint8_t>(verifier, VT_INCLUDE_INSIDE_BAG) &&
           VerifyField<uint8_t>(verifier, VT_INCLUDE_INSIDE_LENGTH) &&
           verifier.EndTable();
  }
  BoundsSensitiveFeaturesT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(BoundsSensitiveFeaturesT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<BoundsSensitiveFeatures> Pack(flatbuffers::FlatBufferBuilder &_fbb, const BoundsSensitiveFeaturesT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct BoundsSensitiveFeaturesBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_enabled(bool enabled) {
    fbb_.AddElement<uint8_t>(BoundsSensitiveFeatures::VT_ENABLED, static_cast<uint8_t>(enabled), 0);
  }
  void add_num_tokens_before(int32_t num_tokens_before) {
    fbb_.AddElement<int32_t>(BoundsSensitiveFeatures::VT_NUM_TOKENS_BEFORE, num_tokens_before, 0);
  }
  void add_num_tokens_inside_left(int32_t num_tokens_inside_left) {
    fbb_.AddElement<int32_t>(BoundsSensitiveFeatures::VT_NUM_TOKENS_INSIDE_LEFT, num_tokens_inside_left, 0);
  }
  void add_num_tokens_inside_right(int32_t num_tokens_inside_right) {
    fbb_.AddElement<int32_t>(BoundsSensitiveFeatures::VT_NUM_TOKENS_INSIDE_RIGHT, num_tokens_inside_right, 0);
  }
  void add_num_tokens_after(int32_t num_tokens_after) {
    fbb_.AddElement<int32_t>(BoundsSensitiveFeatures::VT_NUM_TOKENS_AFTER, num_tokens_after, 0);
  }
  void add_include_inside_bag(bool include_inside_bag) {
    fbb_.AddElement<uint8_t>(BoundsSensitiveFeatures::VT_INCLUDE_INSIDE_BAG, static_cast<uint8_t>(include_inside_bag), 0);
  }
  void add_include_inside_length(bool include_inside_length) {
    fbb_.AddElement<uint8_t>(BoundsSensitiveFeatures::VT_INCLUDE_INSIDE_LENGTH, static_cast<uint8_t>(include_inside_length), 0);
  }
  explicit BoundsSensitiveFeaturesBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BoundsSensitiveFeaturesBuilder &operator=(const BoundsSensitiveFeaturesBuilder &);
  flatbuffers::Offset<BoundsSensitiveFeatures> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BoundsSensitiveFeatures>(end);
    return o;
  }
};

inline flatbuffers::Offset<BoundsSensitiveFeatures> CreateBoundsSensitiveFeatures(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool enabled = false,
    int32_t num_tokens_before = 0,
    int32_t num_tokens_inside_left = 0,
    int32_t num_tokens_inside_right = 0,
    int32_t num_tokens_after = 0,
    bool include_inside_bag = false,
    bool include_inside_length = false) {
  BoundsSensitiveFeaturesBuilder builder_(_fbb);
  builder_.add_num_tokens_after(num_tokens_after);
  builder_.add_num_tokens_inside_right(num_tokens_inside_right);
  builder_.add_num_tokens_inside_left(num_tokens_inside_left);
  builder_.add_num_tokens_before(num_tokens_before);
  builder_.add_include_inside_length(include_inside_length);
  builder_.add_include_inside_bag(include_inside_bag);
  builder_.add_enabled(enabled);
  return builder_.Finish();
}

flatbuffers::Offset<BoundsSensitiveFeatures> CreateBoundsSensitiveFeatures(flatbuffers::FlatBufferBuilder &_fbb, const BoundsSensitiveFeaturesT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

}  // namespace FeatureProcessorOptions_

inline SelectionModelOptionsT *SelectionModelOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new SelectionModelOptionsT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void SelectionModelOptions::UnPackTo(SelectionModelOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = strip_unpaired_brackets(); _o->strip_unpaired_brackets = _e; };
  { auto _e = symmetry_context_size(); _o->symmetry_context_size = _e; };
}

inline flatbuffers::Offset<SelectionModelOptions> SelectionModelOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SelectionModelOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateSelectionModelOptions(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<SelectionModelOptions> CreateSelectionModelOptions(flatbuffers::FlatBufferBuilder &_fbb, const SelectionModelOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SelectionModelOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _strip_unpaired_brackets = _o->strip_unpaired_brackets;
  auto _symmetry_context_size = _o->symmetry_context_size;
  return libtextclassifier2::CreateSelectionModelOptions(
      _fbb,
      _strip_unpaired_brackets,
      _symmetry_context_size);
}

inline ClassificationModelOptionsT *ClassificationModelOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new ClassificationModelOptionsT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void ClassificationModelOptions::UnPackTo(ClassificationModelOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = phone_min_num_digits(); _o->phone_min_num_digits = _e; };
  { auto _e = phone_max_num_digits(); _o->phone_max_num_digits = _e; };
}

inline flatbuffers::Offset<ClassificationModelOptions> ClassificationModelOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ClassificationModelOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateClassificationModelOptions(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<ClassificationModelOptions> CreateClassificationModelOptions(flatbuffers::FlatBufferBuilder &_fbb, const ClassificationModelOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ClassificationModelOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _phone_min_num_digits = _o->phone_min_num_digits;
  auto _phone_max_num_digits = _o->phone_max_num_digits;
  return libtextclassifier2::CreateClassificationModelOptions(
      _fbb,
      _phone_min_num_digits,
      _phone_max_num_digits);
}

inline RegexModelOptionsT *RegexModelOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new RegexModelOptionsT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void RegexModelOptions::UnPackTo(RegexModelOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = patterns(); if (_e) { _o->patterns.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->patterns[_i] = std::unique_ptr<libtextclassifier2::RegexModelOptions_::PatternT>(_e->Get(_i)->UnPack(_resolver)); } } };
}

inline flatbuffers::Offset<RegexModelOptions> RegexModelOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegexModelOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateRegexModelOptions(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<RegexModelOptions> CreateRegexModelOptions(flatbuffers::FlatBufferBuilder &_fbb, const RegexModelOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const RegexModelOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _patterns = _o->patterns.size() ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::RegexModelOptions_::Pattern>> (_o->patterns.size(), [](size_t i, _VectorArgs *__va) { return CreatePattern(*__va->__fbb, __va->__o->patterns[i].get(), __va->__rehasher); }, &_va ) : 0;
  return libtextclassifier2::CreateRegexModelOptions(
      _fbb,
      _patterns);
}

namespace RegexModelOptions_ {

inline PatternT *Pattern::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new PatternT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void Pattern::UnPackTo(PatternT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = collection_name(); if (_e) _o->collection_name = _e->str(); };
  { auto _e = pattern(); if (_e) _o->pattern = _e->str(); };
}

inline flatbuffers::Offset<Pattern> Pattern::Pack(flatbuffers::FlatBufferBuilder &_fbb, const PatternT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreatePattern(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<Pattern> CreatePattern(flatbuffers::FlatBufferBuilder &_fbb, const PatternT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const PatternT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _collection_name = _o->collection_name.empty() ? 0 : _fbb.CreateString(_o->collection_name);
  auto _pattern = _o->pattern.empty() ? 0 : _fbb.CreateString(_o->pattern);
  return libtextclassifier2::RegexModelOptions_::CreatePattern(
      _fbb,
      _collection_name,
      _pattern);
}

}  // namespace RegexModelOptions_

inline StructuredRegexModelT *StructuredRegexModel::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new StructuredRegexModelT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void StructuredRegexModel::UnPackTo(StructuredRegexModelT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = patterns(); if (_e) { _o->patterns.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->patterns[_i] = std::unique_ptr<libtextclassifier2::StructuredRegexModel_::StructuredPatternT>(_e->Get(_i)->UnPack(_resolver)); } } };
}

inline flatbuffers::Offset<StructuredRegexModel> StructuredRegexModel::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StructuredRegexModelT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateStructuredRegexModel(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<StructuredRegexModel> CreateStructuredRegexModel(flatbuffers::FlatBufferBuilder &_fbb, const StructuredRegexModelT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StructuredRegexModelT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _patterns = _o->patterns.size() ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::StructuredRegexModel_::StructuredPattern>> (_o->patterns.size(), [](size_t i, _VectorArgs *__va) { return CreateStructuredPattern(*__va->__fbb, __va->__o->patterns[i].get(), __va->__rehasher); }, &_va ) : 0;
  return libtextclassifier2::CreateStructuredRegexModel(
      _fbb,
      _patterns);
}

namespace StructuredRegexModel_ {

inline StructuredPatternT *StructuredPattern::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new StructuredPatternT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void StructuredPattern::UnPackTo(StructuredPatternT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = pattern(); if (_e) _o->pattern = _e->str(); };
  { auto _e = node_names(); if (_e) { _o->node_names.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->node_names[_i] = _e->Get(_i)->str(); } } };
}

inline flatbuffers::Offset<StructuredPattern> StructuredPattern::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StructuredPatternT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateStructuredPattern(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<StructuredPattern> CreateStructuredPattern(flatbuffers::FlatBufferBuilder &_fbb, const StructuredPatternT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StructuredPatternT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _pattern = _o->pattern.empty() ? 0 : _fbb.CreateString(_o->pattern);
  auto _node_names = _o->node_names.size() ? _fbb.CreateVectorOfStrings(_o->node_names) : 0;
  return libtextclassifier2::StructuredRegexModel_::CreateStructuredPattern(
      _fbb,
      _pattern,
      _node_names);
}

}  // namespace StructuredRegexModel_

inline ModelT *Model::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new ModelT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void Model::UnPackTo(ModelT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = language(); if (_e) _o->language = _e->str(); };
  { auto _e = version(); _o->version = _e; };
  { auto _e = selection_feature_options(); if (_e) _o->selection_feature_options = std::unique_ptr<FeatureProcessorOptionsT>(_e->UnPack(_resolver)); };
  { auto _e = classification_feature_options(); if (_e) _o->classification_feature_options = std::unique_ptr<FeatureProcessorOptionsT>(_e->UnPack(_resolver)); };
  { auto _e = selection_model(); if (_e) { _o->selection_model.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->selection_model[_i] = _e->Get(_i); } } };
  { auto _e = classification_model(); if (_e) { _o->classification_model.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->classification_model[_i] = _e->Get(_i); } } };
  { auto _e = embedding_model(); if (_e) { _o->embedding_model.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->embedding_model[_i] = _e->Get(_i); } } };
  { auto _e = regex_options(); if (_e) _o->regex_options = std::unique_ptr<RegexModelOptionsT>(_e->UnPack(_resolver)); };
  { auto _e = selection_options(); if (_e) _o->selection_options = std::unique_ptr<SelectionModelOptionsT>(_e->UnPack(_resolver)); };
  { auto _e = classification_options(); if (_e) _o->classification_options = std::unique_ptr<ClassificationModelOptionsT>(_e->UnPack(_resolver)); };
  { auto _e = regex_model(); if (_e) _o->regex_model = std::unique_ptr<StructuredRegexModelT>(_e->UnPack(_resolver)); };
}

inline flatbuffers::Offset<Model> Model::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ModelT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateModel(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<Model> CreateModel(flatbuffers::FlatBufferBuilder &_fbb, const ModelT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ModelT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _language = _o->language.empty() ? 0 : _fbb.CreateString(_o->language);
  auto _version = _o->version;
  auto _selection_feature_options = _o->selection_feature_options ? CreateFeatureProcessorOptions(_fbb, _o->selection_feature_options.get(), _rehasher) : 0;
  auto _classification_feature_options = _o->classification_feature_options ? CreateFeatureProcessorOptions(_fbb, _o->classification_feature_options.get(), _rehasher) : 0;
  auto _selection_model = _o->selection_model.size() ? _fbb.CreateVector(_o->selection_model) : 0;
  auto _classification_model = _o->classification_model.size() ? _fbb.CreateVector(_o->classification_model) : 0;
  auto _embedding_model = _o->embedding_model.size() ? _fbb.CreateVector(_o->embedding_model) : 0;
  auto _regex_options = _o->regex_options ? CreateRegexModelOptions(_fbb, _o->regex_options.get(), _rehasher) : 0;
  auto _selection_options = _o->selection_options ? CreateSelectionModelOptions(_fbb, _o->selection_options.get(), _rehasher) : 0;
  auto _classification_options = _o->classification_options ? CreateClassificationModelOptions(_fbb, _o->classification_options.get(), _rehasher) : 0;
  auto _regex_model = _o->regex_model ? CreateStructuredRegexModel(_fbb, _o->regex_model.get(), _rehasher) : 0;
  return libtextclassifier2::CreateModel(
      _fbb,
      _language,
      _version,
      _selection_feature_options,
      _classification_feature_options,
      _selection_model,
      _classification_model,
      _embedding_model,
      _regex_options,
      _selection_options,
      _classification_options,
      _regex_model);
}

inline TokenizationCodepointRangeT *TokenizationCodepointRange::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new TokenizationCodepointRangeT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void TokenizationCodepointRange::UnPackTo(TokenizationCodepointRangeT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = start(); _o->start = _e; };
  { auto _e = end(); _o->end = _e; };
  { auto _e = role(); _o->role = _e; };
  { auto _e = script_id(); _o->script_id = _e; };
}

inline flatbuffers::Offset<TokenizationCodepointRange> TokenizationCodepointRange::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TokenizationCodepointRangeT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateTokenizationCodepointRange(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<TokenizationCodepointRange> CreateTokenizationCodepointRange(flatbuffers::FlatBufferBuilder &_fbb, const TokenizationCodepointRangeT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TokenizationCodepointRangeT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _start = _o->start;
  auto _end = _o->end;
  auto _role = _o->role;
  auto _script_id = _o->script_id;
  return libtextclassifier2::CreateTokenizationCodepointRange(
      _fbb,
      _start,
      _end,
      _role,
      _script_id);
}

inline FeatureProcessorOptionsT *FeatureProcessorOptions::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new FeatureProcessorOptionsT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void FeatureProcessorOptions::UnPackTo(FeatureProcessorOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = num_buckets(); _o->num_buckets = _e; };
  { auto _e = embedding_size(); _o->embedding_size = _e; };
  { auto _e = context_size(); _o->context_size = _e; };
  { auto _e = max_selection_span(); _o->max_selection_span = _e; };
  { auto _e = chargram_orders(); if (_e) { _o->chargram_orders.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->chargram_orders[_i] = _e->Get(_i); } } };
  { auto _e = max_word_length(); _o->max_word_length = _e; };
  { auto _e = unicode_aware_features(); _o->unicode_aware_features = _e; };
  { auto _e = extract_case_feature(); _o->extract_case_feature = _e; };
  { auto _e = extract_selection_mask_feature(); _o->extract_selection_mask_feature = _e; };
  { auto _e = regexp_feature(); if (_e) { _o->regexp_feature.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->regexp_feature[_i] = _e->Get(_i)->str(); } } };
  { auto _e = remap_digits(); _o->remap_digits = _e; };
  { auto _e = lowercase_tokens(); _o->lowercase_tokens = _e; };
  { auto _e = selection_reduced_output_space(); _o->selection_reduced_output_space = _e; };
  { auto _e = collections(); if (_e) { _o->collections.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->collections[_i] = _e->Get(_i)->str(); } } };
  { auto _e = default_collection(); _o->default_collection = _e; };
  { auto _e = only_use_line_with_click(); _o->only_use_line_with_click = _e; };
  { auto _e = split_tokens_on_selection_boundaries(); _o->split_tokens_on_selection_boundaries = _e; };
  { auto _e = tokenization_codepoint_config(); if (_e) { _o->tokenization_codepoint_config.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->tokenization_codepoint_config[_i] = std::unique_ptr<TokenizationCodepointRangeT>(_e->Get(_i)->UnPack(_resolver)); } } };
  { auto _e = center_token_selection_method(); _o->center_token_selection_method = _e; };
  { auto _e = snap_label_span_boundaries_to_containing_tokens(); _o->snap_label_span_boundaries_to_containing_tokens = _e; };
  { auto _e = supported_codepoint_ranges(); if (_e) { _o->supported_codepoint_ranges.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->supported_codepoint_ranges[_i] = std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::CodepointRangeT>(_e->Get(_i)->UnPack(_resolver)); } } };
  { auto _e = internal_tokenizer_codepoint_ranges(); if (_e) { _o->internal_tokenizer_codepoint_ranges.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->internal_tokenizer_codepoint_ranges[_i] = std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::CodepointRangeT>(_e->Get(_i)->UnPack(_resolver)); } } };
  { auto _e = min_supported_codepoint_ratio(); _o->min_supported_codepoint_ratio = _e; };
  { auto _e = feature_version(); _o->feature_version = _e; };
  { auto _e = tokenization_type(); _o->tokenization_type = _e; };
  { auto _e = icu_preserve_whitespace_tokens(); _o->icu_preserve_whitespace_tokens = _e; };
  { auto _e = ignored_span_boundary_codepoints(); if (_e) { _o->ignored_span_boundary_codepoints.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->ignored_span_boundary_codepoints[_i] = _e->Get(_i); } } };
  { auto _e = click_random_token_in_selection(); _o->click_random_token_in_selection = _e; };
  { auto _e = alternative_collection_map(); if (_e) { _o->alternative_collection_map.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->alternative_collection_map[_i] = std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntryT>(_e->Get(_i)->UnPack(_resolver)); } } };
  { auto _e = bounds_sensitive_features(); if (_e) _o->bounds_sensitive_features = std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeaturesT>(_e->UnPack(_resolver)); };
  { auto _e = split_selection_candidates(); _o->split_selection_candidates = _e; };
  { auto _e = allowed_chargrams(); if (_e) { _o->allowed_chargrams.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->allowed_chargrams[_i] = _e->Get(_i)->str(); } } };
  { auto _e = tokenize_on_script_change(); _o->tokenize_on_script_change = _e; };
}

inline flatbuffers::Offset<FeatureProcessorOptions> FeatureProcessorOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FeatureProcessorOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateFeatureProcessorOptions(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<FeatureProcessorOptions> CreateFeatureProcessorOptions(flatbuffers::FlatBufferBuilder &_fbb, const FeatureProcessorOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FeatureProcessorOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _num_buckets = _o->num_buckets;
  auto _embedding_size = _o->embedding_size;
  auto _context_size = _o->context_size;
  auto _max_selection_span = _o->max_selection_span;
  auto _chargram_orders = _o->chargram_orders.size() ? _fbb.CreateVector(_o->chargram_orders) : 0;
  auto _max_word_length = _o->max_word_length;
  auto _unicode_aware_features = _o->unicode_aware_features;
  auto _extract_case_feature = _o->extract_case_feature;
  auto _extract_selection_mask_feature = _o->extract_selection_mask_feature;
  auto _regexp_feature = _o->regexp_feature.size() ? _fbb.CreateVectorOfStrings(_o->regexp_feature) : 0;
  auto _remap_digits = _o->remap_digits;
  auto _lowercase_tokens = _o->lowercase_tokens;
  auto _selection_reduced_output_space = _o->selection_reduced_output_space;
  auto _collections = _o->collections.size() ? _fbb.CreateVectorOfStrings(_o->collections) : 0;
  auto _default_collection = _o->default_collection;
  auto _only_use_line_with_click = _o->only_use_line_with_click;
  auto _split_tokens_on_selection_boundaries = _o->split_tokens_on_selection_boundaries;
  auto _tokenization_codepoint_config = _o->tokenization_codepoint_config.size() ? _fbb.CreateVector<flatbuffers::Offset<TokenizationCodepointRange>> (_o->tokenization_codepoint_config.size(), [](size_t i, _VectorArgs *__va) { return CreateTokenizationCodepointRange(*__va->__fbb, __va->__o->tokenization_codepoint_config[i].get(), __va->__rehasher); }, &_va ) : 0;
  auto _center_token_selection_method = _o->center_token_selection_method;
  auto _snap_label_span_boundaries_to_containing_tokens = _o->snap_label_span_boundaries_to_containing_tokens;
  auto _supported_codepoint_ranges = _o->supported_codepoint_ranges.size() ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> (_o->supported_codepoint_ranges.size(), [](size_t i, _VectorArgs *__va) { return CreateCodepointRange(*__va->__fbb, __va->__o->supported_codepoint_ranges[i].get(), __va->__rehasher); }, &_va ) : 0;
  auto _internal_tokenizer_codepoint_ranges = _o->internal_tokenizer_codepoint_ranges.size() ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CodepointRange>> (_o->internal_tokenizer_codepoint_ranges.size(), [](size_t i, _VectorArgs *__va) { return CreateCodepointRange(*__va->__fbb, __va->__o->internal_tokenizer_codepoint_ranges[i].get(), __va->__rehasher); }, &_va ) : 0;
  auto _min_supported_codepoint_ratio = _o->min_supported_codepoint_ratio;
  auto _feature_version = _o->feature_version;
  auto _tokenization_type = _o->tokenization_type;
  auto _icu_preserve_whitespace_tokens = _o->icu_preserve_whitespace_tokens;
  auto _ignored_span_boundary_codepoints = _o->ignored_span_boundary_codepoints.size() ? _fbb.CreateVector(_o->ignored_span_boundary_codepoints) : 0;
  auto _click_random_token_in_selection = _o->click_random_token_in_selection;
  auto _alternative_collection_map = _o->alternative_collection_map.size() ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::CollectionMapEntry>> (_o->alternative_collection_map.size(), [](size_t i, _VectorArgs *__va) { return CreateCollectionMapEntry(*__va->__fbb, __va->__o->alternative_collection_map[i].get(), __va->__rehasher); }, &_va ) : 0;
  auto _bounds_sensitive_features = _o->bounds_sensitive_features ? CreateBoundsSensitiveFeatures(_fbb, _o->bounds_sensitive_features.get(), _rehasher) : 0;
  auto _split_selection_candidates = _o->split_selection_candidates;
  auto _allowed_chargrams = _o->allowed_chargrams.size() ? _fbb.CreateVectorOfStrings(_o->allowed_chargrams) : 0;
  auto _tokenize_on_script_change = _o->tokenize_on_script_change;
  return libtextclassifier2::CreateFeatureProcessorOptions(
      _fbb,
      _num_buckets,
      _embedding_size,
      _context_size,
      _max_selection_span,
      _chargram_orders,
      _max_word_length,
      _unicode_aware_features,
      _extract_case_feature,
      _extract_selection_mask_feature,
      _regexp_feature,
      _remap_digits,
      _lowercase_tokens,
      _selection_reduced_output_space,
      _collections,
      _default_collection,
      _only_use_line_with_click,
      _split_tokens_on_selection_boundaries,
      _tokenization_codepoint_config,
      _center_token_selection_method,
      _snap_label_span_boundaries_to_containing_tokens,
      _supported_codepoint_ranges,
      _internal_tokenizer_codepoint_ranges,
      _min_supported_codepoint_ratio,
      _feature_version,
      _tokenization_type,
      _icu_preserve_whitespace_tokens,
      _ignored_span_boundary_codepoints,
      _click_random_token_in_selection,
      _alternative_collection_map,
      _bounds_sensitive_features,
      _split_selection_candidates,
      _allowed_chargrams,
      _tokenize_on_script_change);
}

namespace FeatureProcessorOptions_ {

inline CodepointRangeT *CodepointRange::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new CodepointRangeT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void CodepointRange::UnPackTo(CodepointRangeT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = start(); _o->start = _e; };
  { auto _e = end(); _o->end = _e; };
}

inline flatbuffers::Offset<CodepointRange> CodepointRange::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CodepointRangeT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateCodepointRange(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<CodepointRange> CreateCodepointRange(flatbuffers::FlatBufferBuilder &_fbb, const CodepointRangeT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CodepointRangeT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _start = _o->start;
  auto _end = _o->end;
  return libtextclassifier2::FeatureProcessorOptions_::CreateCodepointRange(
      _fbb,
      _start,
      _end);
}

inline CollectionMapEntryT *CollectionMapEntry::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new CollectionMapEntryT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void CollectionMapEntry::UnPackTo(CollectionMapEntryT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = key(); if (_e) _o->key = _e->str(); };
  { auto _e = value(); if (_e) _o->value = _e->str(); };
}

inline flatbuffers::Offset<CollectionMapEntry> CollectionMapEntry::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CollectionMapEntryT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateCollectionMapEntry(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<CollectionMapEntry> CreateCollectionMapEntry(flatbuffers::FlatBufferBuilder &_fbb, const CollectionMapEntryT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CollectionMapEntryT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _key = _o->key.empty() ? 0 : _fbb.CreateString(_o->key);
  auto _value = _o->value.empty() ? 0 : _fbb.CreateString(_o->value);
  return libtextclassifier2::FeatureProcessorOptions_::CreateCollectionMapEntry(
      _fbb,
      _key,
      _value);
}

inline BoundsSensitiveFeaturesT *BoundsSensitiveFeatures::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
  auto _o = new BoundsSensitiveFeaturesT();
  UnPackTo(_o, _resolver);
  return _o;
}

inline void BoundsSensitiveFeatures::UnPackTo(BoundsSensitiveFeaturesT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = enabled(); _o->enabled = _e; };
  { auto _e = num_tokens_before(); _o->num_tokens_before = _e; };
  { auto _e = num_tokens_inside_left(); _o->num_tokens_inside_left = _e; };
  { auto _e = num_tokens_inside_right(); _o->num_tokens_inside_right = _e; };
  { auto _e = num_tokens_after(); _o->num_tokens_after = _e; };
  { auto _e = include_inside_bag(); _o->include_inside_bag = _e; };
  { auto _e = include_inside_length(); _o->include_inside_length = _e; };
}

inline flatbuffers::Offset<BoundsSensitiveFeatures> BoundsSensitiveFeatures::Pack(flatbuffers::FlatBufferBuilder &_fbb, const BoundsSensitiveFeaturesT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateBoundsSensitiveFeatures(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<BoundsSensitiveFeatures> CreateBoundsSensitiveFeatures(flatbuffers::FlatBufferBuilder &_fbb, const BoundsSensitiveFeaturesT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const BoundsSensitiveFeaturesT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _enabled = _o->enabled;
  auto _num_tokens_before = _o->num_tokens_before;
  auto _num_tokens_inside_left = _o->num_tokens_inside_left;
  auto _num_tokens_inside_right = _o->num_tokens_inside_right;
  auto _num_tokens_after = _o->num_tokens_after;
  auto _include_inside_bag = _o->include_inside_bag;
  auto _include_inside_length = _o->include_inside_length;
  return libtextclassifier2::FeatureProcessorOptions_::CreateBoundsSensitiveFeatures(
      _fbb,
      _enabled,
      _num_tokens_before,
      _num_tokens_inside_left,
      _num_tokens_inside_right,
      _num_tokens_after,
      _include_inside_bag,
      _include_inside_length);
}

}  // namespace FeatureProcessorOptions_
}  // namespace libtextclassifier2

#endif  // FLATBUFFERS_GENERATED_MODEL_LIBTEXTCLASSIFIER2_FEATUREPROCESSOROPTIONS__H_
