/*
 * 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_H_
#define FLATBUFFERS_GENERATED_MODEL_LIBTEXTCLASSIFIER2_H_

#include "flatbuffers/flatbuffers.h"

namespace libtextclassifier2 {

struct SelectionModelOptions;
struct SelectionModelOptionsT;

struct ClassificationModelOptions;
struct ClassificationModelOptionsT;

namespace RegexModel_ {

struct Pattern;
struct PatternT;

}  // namespace RegexModel_

struct RegexModel;
struct RegexModelT;

struct DatetimeModelPattern;
struct DatetimeModelPatternT;

struct DatetimeModelExtractor;
struct DatetimeModelExtractorT;

struct DatetimeModel;
struct DatetimeModelT;

struct ModelTriggeringOptions;
struct ModelTriggeringOptionsT;

struct Model;
struct ModelT;

struct TokenizationCodepointRange;
struct TokenizationCodepointRangeT;

namespace FeatureProcessorOptions_ {

struct CodepointRange;
struct CodepointRangeT;

struct BoundsSensitiveFeatures;
struct BoundsSensitiveFeaturesT;

struct AlternativeCollectionMapEntry;
struct AlternativeCollectionMapEntryT;

}  // namespace FeatureProcessorOptions_

struct FeatureProcessorOptions;
struct FeatureProcessorOptionsT;

enum DatetimeExtractorType {
  DatetimeExtractorType_UNKNOWN_DATETIME_EXTRACTOR_TYPE = 0,
  DatetimeExtractorType_AM = 1,
  DatetimeExtractorType_PM = 2,
  DatetimeExtractorType_JANUARY = 3,
  DatetimeExtractorType_FEBRUARY = 4,
  DatetimeExtractorType_MARCH = 5,
  DatetimeExtractorType_APRIL = 6,
  DatetimeExtractorType_MAY = 7,
  DatetimeExtractorType_JUNE = 8,
  DatetimeExtractorType_JULY = 9,
  DatetimeExtractorType_AUGUST = 10,
  DatetimeExtractorType_SEPTEMBER = 11,
  DatetimeExtractorType_OCTOBER = 12,
  DatetimeExtractorType_NOVEMBER = 13,
  DatetimeExtractorType_DECEMBER = 14,
  DatetimeExtractorType_NEXT = 15,
  DatetimeExtractorType_NEXT_OR_SAME = 16,
  DatetimeExtractorType_LAST = 17,
  DatetimeExtractorType_NOW = 18,
  DatetimeExtractorType_TOMORROW = 19,
  DatetimeExtractorType_YESTERDAY = 20,
  DatetimeExtractorType_PAST = 21,
  DatetimeExtractorType_FUTURE = 22,
  DatetimeExtractorType_DAY = 23,
  DatetimeExtractorType_WEEK = 24,
  DatetimeExtractorType_MONTH = 25,
  DatetimeExtractorType_YEAR = 26,
  DatetimeExtractorType_MONDAY = 27,
  DatetimeExtractorType_TUESDAY = 28,
  DatetimeExtractorType_WEDNESDAY = 29,
  DatetimeExtractorType_THURSDAY = 30,
  DatetimeExtractorType_FRIDAY = 31,
  DatetimeExtractorType_SATURDAY = 32,
  DatetimeExtractorType_SUNDAY = 33,
  DatetimeExtractorType_DAYS = 34,
  DatetimeExtractorType_WEEKS = 35,
  DatetimeExtractorType_MONTHS = 36,
  DatetimeExtractorType_HOURS = 37,
  DatetimeExtractorType_MINUTES = 38,
  DatetimeExtractorType_SECONDS = 39,
  DatetimeExtractorType_YEARS = 40,
  DatetimeExtractorType_DIGITS = 41,
  DatetimeExtractorType_SIGNEDDIGITS = 42,
  DatetimeExtractorType_ZERO = 43,
  DatetimeExtractorType_ONE = 44,
  DatetimeExtractorType_TWO = 45,
  DatetimeExtractorType_THREE = 46,
  DatetimeExtractorType_FOUR = 47,
  DatetimeExtractorType_FIVE = 48,
  DatetimeExtractorType_SIX = 49,
  DatetimeExtractorType_SEVEN = 50,
  DatetimeExtractorType_EIGHT = 51,
  DatetimeExtractorType_NINE = 52,
  DatetimeExtractorType_TEN = 53,
  DatetimeExtractorType_ELEVEN = 54,
  DatetimeExtractorType_TWELVE = 55,
  DatetimeExtractorType_THIRTEEN = 56,
  DatetimeExtractorType_FOURTEEN = 57,
  DatetimeExtractorType_FIFTEEN = 58,
  DatetimeExtractorType_SIXTEEN = 59,
  DatetimeExtractorType_SEVENTEEN = 60,
  DatetimeExtractorType_EIGHTEEN = 61,
  DatetimeExtractorType_NINETEEN = 62,
  DatetimeExtractorType_TWENTY = 63,
  DatetimeExtractorType_THIRTY = 64,
  DatetimeExtractorType_FORTY = 65,
  DatetimeExtractorType_FIFTY = 66,
  DatetimeExtractorType_SIXTY = 67,
  DatetimeExtractorType_SEVENTY = 68,
  DatetimeExtractorType_EIGHTY = 69,
  DatetimeExtractorType_NINETY = 70,
  DatetimeExtractorType_HUNDRED = 71,
  DatetimeExtractorType_THOUSAND = 72,
  DatetimeExtractorType_MIN = DatetimeExtractorType_UNKNOWN_DATETIME_EXTRACTOR_TYPE,
  DatetimeExtractorType_MAX = DatetimeExtractorType_THOUSAND
};

inline DatetimeExtractorType (&EnumValuesDatetimeExtractorType())[73] {
  static DatetimeExtractorType values[] = {
    DatetimeExtractorType_UNKNOWN_DATETIME_EXTRACTOR_TYPE,
    DatetimeExtractorType_AM,
    DatetimeExtractorType_PM,
    DatetimeExtractorType_JANUARY,
    DatetimeExtractorType_FEBRUARY,
    DatetimeExtractorType_MARCH,
    DatetimeExtractorType_APRIL,
    DatetimeExtractorType_MAY,
    DatetimeExtractorType_JUNE,
    DatetimeExtractorType_JULY,
    DatetimeExtractorType_AUGUST,
    DatetimeExtractorType_SEPTEMBER,
    DatetimeExtractorType_OCTOBER,
    DatetimeExtractorType_NOVEMBER,
    DatetimeExtractorType_DECEMBER,
    DatetimeExtractorType_NEXT,
    DatetimeExtractorType_NEXT_OR_SAME,
    DatetimeExtractorType_LAST,
    DatetimeExtractorType_NOW,
    DatetimeExtractorType_TOMORROW,
    DatetimeExtractorType_YESTERDAY,
    DatetimeExtractorType_PAST,
    DatetimeExtractorType_FUTURE,
    DatetimeExtractorType_DAY,
    DatetimeExtractorType_WEEK,
    DatetimeExtractorType_MONTH,
    DatetimeExtractorType_YEAR,
    DatetimeExtractorType_MONDAY,
    DatetimeExtractorType_TUESDAY,
    DatetimeExtractorType_WEDNESDAY,
    DatetimeExtractorType_THURSDAY,
    DatetimeExtractorType_FRIDAY,
    DatetimeExtractorType_SATURDAY,
    DatetimeExtractorType_SUNDAY,
    DatetimeExtractorType_DAYS,
    DatetimeExtractorType_WEEKS,
    DatetimeExtractorType_MONTHS,
    DatetimeExtractorType_HOURS,
    DatetimeExtractorType_MINUTES,
    DatetimeExtractorType_SECONDS,
    DatetimeExtractorType_YEARS,
    DatetimeExtractorType_DIGITS,
    DatetimeExtractorType_SIGNEDDIGITS,
    DatetimeExtractorType_ZERO,
    DatetimeExtractorType_ONE,
    DatetimeExtractorType_TWO,
    DatetimeExtractorType_THREE,
    DatetimeExtractorType_FOUR,
    DatetimeExtractorType_FIVE,
    DatetimeExtractorType_SIX,
    DatetimeExtractorType_SEVEN,
    DatetimeExtractorType_EIGHT,
    DatetimeExtractorType_NINE,
    DatetimeExtractorType_TEN,
    DatetimeExtractorType_ELEVEN,
    DatetimeExtractorType_TWELVE,
    DatetimeExtractorType_THIRTEEN,
    DatetimeExtractorType_FOURTEEN,
    DatetimeExtractorType_FIFTEEN,
    DatetimeExtractorType_SIXTEEN,
    DatetimeExtractorType_SEVENTEEN,
    DatetimeExtractorType_EIGHTEEN,
    DatetimeExtractorType_NINETEEN,
    DatetimeExtractorType_TWENTY,
    DatetimeExtractorType_THIRTY,
    DatetimeExtractorType_FORTY,
    DatetimeExtractorType_FIFTY,
    DatetimeExtractorType_SIXTY,
    DatetimeExtractorType_SEVENTY,
    DatetimeExtractorType_EIGHTY,
    DatetimeExtractorType_NINETY,
    DatetimeExtractorType_HUNDRED,
    DatetimeExtractorType_THOUSAND
  };
  return values;
}

inline const char **EnumNamesDatetimeExtractorType() {
  static const char *names[] = {
    "UNKNOWN_DATETIME_EXTRACTOR_TYPE",
    "AM",
    "PM",
    "JANUARY",
    "FEBRUARY",
    "MARCH",
    "APRIL",
    "MAY",
    "JUNE",
    "JULY",
    "AUGUST",
    "SEPTEMBER",
    "OCTOBER",
    "NOVEMBER",
    "DECEMBER",
    "NEXT",
    "NEXT_OR_SAME",
    "LAST",
    "NOW",
    "TOMORROW",
    "YESTERDAY",
    "PAST",
    "FUTURE",
    "DAY",
    "WEEK",
    "MONTH",
    "YEAR",
    "MONDAY",
    "TUESDAY",
    "WEDNESDAY",
    "THURSDAY",
    "FRIDAY",
    "SATURDAY",
    "SUNDAY",
    "DAYS",
    "WEEKS",
    "MONTHS",
    "HOURS",
    "MINUTES",
    "SECONDS",
    "YEARS",
    "DIGITS",
    "SIGNEDDIGITS",
    "ZERO",
    "ONE",
    "TWO",
    "THREE",
    "FOUR",
    "FIVE",
    "SIX",
    "SEVEN",
    "EIGHT",
    "NINE",
    "TEN",
    "ELEVEN",
    "TWELVE",
    "THIRTEEN",
    "FOURTEEN",
    "FIFTEEN",
    "SIXTEEN",
    "SEVENTEEN",
    "EIGHTEEN",
    "NINETEEN",
    "TWENTY",
    "THIRTY",
    "FORTY",
    "FIFTY",
    "SIXTY",
    "SEVENTY",
    "EIGHTY",
    "NINETY",
    "HUNDRED",
    "THOUSAND",
    nullptr
  };
  return names;
}

inline const char *EnumNameDatetimeExtractorType(DatetimeExtractorType e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesDatetimeExtractorType()[index];
}

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;
  int32_t batch_size;
  SelectionModelOptionsT()
      : strip_unpaired_brackets(true),
        symmetry_context_size(0),
        batch_size(1024) {
  }
};

struct SelectionModelOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SelectionModelOptionsT NativeTableType;
  enum {
    VT_STRIP_UNPAIRED_BRACKETS = 4,
    VT_SYMMETRY_CONTEXT_SIZE = 6,
    VT_BATCH_SIZE = 8
  };
  bool strip_unpaired_brackets() const {
    return GetField<uint8_t>(VT_STRIP_UNPAIRED_BRACKETS, 1) != 0;
  }
  int32_t symmetry_context_size() const {
    return GetField<int32_t>(VT_SYMMETRY_CONTEXT_SIZE, 0);
  }
  int32_t batch_size() const {
    return GetField<int32_t>(VT_BATCH_SIZE, 1024);
  }
  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) &&
           VerifyField<int32_t>(verifier, VT_BATCH_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), 1);
  }
  void add_symmetry_context_size(int32_t symmetry_context_size) {
    fbb_.AddElement<int32_t>(SelectionModelOptions::VT_SYMMETRY_CONTEXT_SIZE, symmetry_context_size, 0);
  }
  void add_batch_size(int32_t batch_size) {
    fbb_.AddElement<int32_t>(SelectionModelOptions::VT_BATCH_SIZE, batch_size, 1024);
  }
  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 = true,
    int32_t symmetry_context_size = 0,
    int32_t batch_size = 1024) {
  SelectionModelOptionsBuilder builder_(_fbb);
  builder_.add_batch_size(batch_size);
  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);

namespace RegexModel_ {

struct PatternT : public flatbuffers::NativeTable {
  typedef Pattern TableType;
  std::string collection_name;
  std::string pattern;
  bool enabled_for_annotation;
  bool enabled_for_classification;
  bool enabled_for_selection;
  float target_classification_score;
  float priority_score;
  PatternT()
      : enabled_for_annotation(false),
        enabled_for_classification(false),
        enabled_for_selection(false),
        target_classification_score(1.0f),
        priority_score(0.0f) {
  }
};

struct Pattern FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PatternT NativeTableType;
  enum {
    VT_COLLECTION_NAME = 4,
    VT_PATTERN = 6,
    VT_ENABLED_FOR_ANNOTATION = 8,
    VT_ENABLED_FOR_CLASSIFICATION = 10,
    VT_ENABLED_FOR_SELECTION = 12,
    VT_TARGET_CLASSIFICATION_SCORE = 14,
    VT_PRIORITY_SCORE = 16
  };
  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 enabled_for_annotation() const {
    return GetField<uint8_t>(VT_ENABLED_FOR_ANNOTATION, 0) != 0;
  }
  bool enabled_for_classification() const {
    return GetField<uint8_t>(VT_ENABLED_FOR_CLASSIFICATION, 0) != 0;
  }
  bool enabled_for_selection() const {
    return GetField<uint8_t>(VT_ENABLED_FOR_SELECTION, 0) != 0;
  }
  float target_classification_score() const {
    return GetField<float>(VT_TARGET_CLASSIFICATION_SCORE, 1.0f);
  }
  float priority_score() const {
    return GetField<float>(VT_PRIORITY_SCORE, 0.0f);
  }
  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()) &&
           VerifyField<uint8_t>(verifier, VT_ENABLED_FOR_ANNOTATION) &&
           VerifyField<uint8_t>(verifier, VT_ENABLED_FOR_CLASSIFICATION) &&
           VerifyField<uint8_t>(verifier, VT_ENABLED_FOR_SELECTION) &&
           VerifyField<float>(verifier, VT_TARGET_CLASSIFICATION_SCORE) &&
           VerifyField<float>(verifier, VT_PRIORITY_SCORE) &&
           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);
  }
  void add_enabled_for_annotation(bool enabled_for_annotation) {
    fbb_.AddElement<uint8_t>(Pattern::VT_ENABLED_FOR_ANNOTATION, static_cast<uint8_t>(enabled_for_annotation), 0);
  }
  void add_enabled_for_classification(bool enabled_for_classification) {
    fbb_.AddElement<uint8_t>(Pattern::VT_ENABLED_FOR_CLASSIFICATION, static_cast<uint8_t>(enabled_for_classification), 0);
  }
  void add_enabled_for_selection(bool enabled_for_selection) {
    fbb_.AddElement<uint8_t>(Pattern::VT_ENABLED_FOR_SELECTION, static_cast<uint8_t>(enabled_for_selection), 0);
  }
  void add_target_classification_score(float target_classification_score) {
    fbb_.AddElement<float>(Pattern::VT_TARGET_CLASSIFICATION_SCORE, target_classification_score, 1.0f);
  }
  void add_priority_score(float priority_score) {
    fbb_.AddElement<float>(Pattern::VT_PRIORITY_SCORE, priority_score, 0.0f);
  }
  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,
    bool enabled_for_annotation = false,
    bool enabled_for_classification = false,
    bool enabled_for_selection = false,
    float target_classification_score = 1.0f,
    float priority_score = 0.0f) {
  PatternBuilder builder_(_fbb);
  builder_.add_priority_score(priority_score);
  builder_.add_target_classification_score(target_classification_score);
  builder_.add_pattern(pattern);
  builder_.add_collection_name(collection_name);
  builder_.add_enabled_for_selection(enabled_for_selection);
  builder_.add_enabled_for_classification(enabled_for_classification);
  builder_.add_enabled_for_annotation(enabled_for_annotation);
  return builder_.Finish();
}

inline flatbuffers::Offset<Pattern> CreatePatternDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *collection_name = nullptr,
    const char *pattern = nullptr,
    bool enabled_for_annotation = false,
    bool enabled_for_classification = false,
    bool enabled_for_selection = false,
    float target_classification_score = 1.0f,
    float priority_score = 0.0f) {
  return libtextclassifier2::RegexModel_::CreatePattern(
      _fbb,
      collection_name ? _fbb.CreateString(collection_name) : 0,
      pattern ? _fbb.CreateString(pattern) : 0,
      enabled_for_annotation,
      enabled_for_classification,
      enabled_for_selection,
      target_classification_score,
      priority_score);
}

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

}  // namespace RegexModel_

struct RegexModelT : public flatbuffers::NativeTable {
  typedef RegexModel TableType;
  std::vector<std::unique_ptr<libtextclassifier2::RegexModel_::PatternT>> patterns;
  RegexModelT() {
  }
};

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

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

inline flatbuffers::Offset<RegexModel> CreateRegexModel(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::RegexModel_::Pattern>>> patterns = 0) {
  RegexModelBuilder builder_(_fbb);
  builder_.add_patterns(patterns);
  return builder_.Finish();
}

inline flatbuffers::Offset<RegexModel> CreateRegexModelDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<libtextclassifier2::RegexModel_::Pattern>> *patterns = nullptr) {
  return libtextclassifier2::CreateRegexModel(
      _fbb,
      patterns ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::RegexModel_::Pattern>>(*patterns) : 0);
}

flatbuffers::Offset<RegexModel> CreateRegexModel(flatbuffers::FlatBufferBuilder &_fbb, const RegexModelT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct DatetimeModelPatternT : public flatbuffers::NativeTable {
  typedef DatetimeModelPattern TableType;
  std::vector<std::string> regexes;
  std::vector<int32_t> locales;
  float target_classification_score;
  float priority_score;
  DatetimeModelPatternT()
      : target_classification_score(1.0f),
        priority_score(0.0f) {
  }
};

struct DatetimeModelPattern FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DatetimeModelPatternT NativeTableType;
  enum {
    VT_REGEXES = 4,
    VT_LOCALES = 6,
    VT_TARGET_CLASSIFICATION_SCORE = 8,
    VT_PRIORITY_SCORE = 10
  };
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *regexes() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_REGEXES);
  }
  const flatbuffers::Vector<int32_t> *locales() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_LOCALES);
  }
  float target_classification_score() const {
    return GetField<float>(VT_TARGET_CLASSIFICATION_SCORE, 1.0f);
  }
  float priority_score() const {
    return GetField<float>(VT_PRIORITY_SCORE, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_REGEXES) &&
           verifier.Verify(regexes()) &&
           verifier.VerifyVectorOfStrings(regexes()) &&
           VerifyOffset(verifier, VT_LOCALES) &&
           verifier.Verify(locales()) &&
           VerifyField<float>(verifier, VT_TARGET_CLASSIFICATION_SCORE) &&
           VerifyField<float>(verifier, VT_PRIORITY_SCORE) &&
           verifier.EndTable();
  }
  DatetimeModelPatternT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(DatetimeModelPatternT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<DatetimeModelPattern> Pack(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelPatternT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct DatetimeModelPatternBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_regexes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> regexes) {
    fbb_.AddOffset(DatetimeModelPattern::VT_REGEXES, regexes);
  }
  void add_locales(flatbuffers::Offset<flatbuffers::Vector<int32_t>> locales) {
    fbb_.AddOffset(DatetimeModelPattern::VT_LOCALES, locales);
  }
  void add_target_classification_score(float target_classification_score) {
    fbb_.AddElement<float>(DatetimeModelPattern::VT_TARGET_CLASSIFICATION_SCORE, target_classification_score, 1.0f);
  }
  void add_priority_score(float priority_score) {
    fbb_.AddElement<float>(DatetimeModelPattern::VT_PRIORITY_SCORE, priority_score, 0.0f);
  }
  explicit DatetimeModelPatternBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DatetimeModelPatternBuilder &operator=(const DatetimeModelPatternBuilder &);
  flatbuffers::Offset<DatetimeModelPattern> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DatetimeModelPattern>(end);
    return o;
  }
};

inline flatbuffers::Offset<DatetimeModelPattern> CreateDatetimeModelPattern(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> regexes = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> locales = 0,
    float target_classification_score = 1.0f,
    float priority_score = 0.0f) {
  DatetimeModelPatternBuilder builder_(_fbb);
  builder_.add_priority_score(priority_score);
  builder_.add_target_classification_score(target_classification_score);
  builder_.add_locales(locales);
  builder_.add_regexes(regexes);
  return builder_.Finish();
}

inline flatbuffers::Offset<DatetimeModelPattern> CreateDatetimeModelPatternDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *regexes = nullptr,
    const std::vector<int32_t> *locales = nullptr,
    float target_classification_score = 1.0f,
    float priority_score = 0.0f) {
  return libtextclassifier2::CreateDatetimeModelPattern(
      _fbb,
      regexes ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*regexes) : 0,
      locales ? _fbb.CreateVector<int32_t>(*locales) : 0,
      target_classification_score,
      priority_score);
}

flatbuffers::Offset<DatetimeModelPattern> CreateDatetimeModelPattern(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelPatternT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct DatetimeModelExtractorT : public flatbuffers::NativeTable {
  typedef DatetimeModelExtractor TableType;
  DatetimeExtractorType extractor;
  std::string pattern;
  std::vector<int32_t> locales;
  DatetimeModelExtractorT()
      : extractor(DatetimeExtractorType_UNKNOWN_DATETIME_EXTRACTOR_TYPE) {
  }
};

struct DatetimeModelExtractor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DatetimeModelExtractorT NativeTableType;
  enum {
    VT_EXTRACTOR = 4,
    VT_PATTERN = 6,
    VT_LOCALES = 8
  };
  DatetimeExtractorType extractor() const {
    return static_cast<DatetimeExtractorType>(GetField<int32_t>(VT_EXTRACTOR, 0));
  }
  const flatbuffers::String *pattern() const {
    return GetPointer<const flatbuffers::String *>(VT_PATTERN);
  }
  const flatbuffers::Vector<int32_t> *locales() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_LOCALES);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_EXTRACTOR) &&
           VerifyOffset(verifier, VT_PATTERN) &&
           verifier.Verify(pattern()) &&
           VerifyOffset(verifier, VT_LOCALES) &&
           verifier.Verify(locales()) &&
           verifier.EndTable();
  }
  DatetimeModelExtractorT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(DatetimeModelExtractorT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<DatetimeModelExtractor> Pack(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelExtractorT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct DatetimeModelExtractorBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_extractor(DatetimeExtractorType extractor) {
    fbb_.AddElement<int32_t>(DatetimeModelExtractor::VT_EXTRACTOR, static_cast<int32_t>(extractor), 0);
  }
  void add_pattern(flatbuffers::Offset<flatbuffers::String> pattern) {
    fbb_.AddOffset(DatetimeModelExtractor::VT_PATTERN, pattern);
  }
  void add_locales(flatbuffers::Offset<flatbuffers::Vector<int32_t>> locales) {
    fbb_.AddOffset(DatetimeModelExtractor::VT_LOCALES, locales);
  }
  explicit DatetimeModelExtractorBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DatetimeModelExtractorBuilder &operator=(const DatetimeModelExtractorBuilder &);
  flatbuffers::Offset<DatetimeModelExtractor> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DatetimeModelExtractor>(end);
    return o;
  }
};

inline flatbuffers::Offset<DatetimeModelExtractor> CreateDatetimeModelExtractor(
    flatbuffers::FlatBufferBuilder &_fbb,
    DatetimeExtractorType extractor = DatetimeExtractorType_UNKNOWN_DATETIME_EXTRACTOR_TYPE,
    flatbuffers::Offset<flatbuffers::String> pattern = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> locales = 0) {
  DatetimeModelExtractorBuilder builder_(_fbb);
  builder_.add_locales(locales);
  builder_.add_pattern(pattern);
  builder_.add_extractor(extractor);
  return builder_.Finish();
}

inline flatbuffers::Offset<DatetimeModelExtractor> CreateDatetimeModelExtractorDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    DatetimeExtractorType extractor = DatetimeExtractorType_UNKNOWN_DATETIME_EXTRACTOR_TYPE,
    const char *pattern = nullptr,
    const std::vector<int32_t> *locales = nullptr) {
  return libtextclassifier2::CreateDatetimeModelExtractor(
      _fbb,
      extractor,
      pattern ? _fbb.CreateString(pattern) : 0,
      locales ? _fbb.CreateVector<int32_t>(*locales) : 0);
}

flatbuffers::Offset<DatetimeModelExtractor> CreateDatetimeModelExtractor(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelExtractorT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct DatetimeModelT : public flatbuffers::NativeTable {
  typedef DatetimeModel TableType;
  std::vector<std::string> locales;
  std::vector<std::unique_ptr<DatetimeModelPatternT>> patterns;
  std::vector<std::unique_ptr<DatetimeModelExtractorT>> extractors;
  DatetimeModelT() {
  }
};

struct DatetimeModel FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DatetimeModelT NativeTableType;
  enum {
    VT_LOCALES = 4,
    VT_PATTERNS = 6,
    VT_EXTRACTORS = 8
  };
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *locales() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_LOCALES);
  }
  const flatbuffers::Vector<flatbuffers::Offset<DatetimeModelPattern>> *patterns() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<DatetimeModelPattern>> *>(VT_PATTERNS);
  }
  const flatbuffers::Vector<flatbuffers::Offset<DatetimeModelExtractor>> *extractors() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<DatetimeModelExtractor>> *>(VT_EXTRACTORS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_LOCALES) &&
           verifier.Verify(locales()) &&
           verifier.VerifyVectorOfStrings(locales()) &&
           VerifyOffset(verifier, VT_PATTERNS) &&
           verifier.Verify(patterns()) &&
           verifier.VerifyVectorOfTables(patterns()) &&
           VerifyOffset(verifier, VT_EXTRACTORS) &&
           verifier.Verify(extractors()) &&
           verifier.VerifyVectorOfTables(extractors()) &&
           verifier.EndTable();
  }
  DatetimeModelT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(DatetimeModelT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<DatetimeModel> Pack(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct DatetimeModelBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_locales(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> locales) {
    fbb_.AddOffset(DatetimeModel::VT_LOCALES, locales);
  }
  void add_patterns(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<DatetimeModelPattern>>> patterns) {
    fbb_.AddOffset(DatetimeModel::VT_PATTERNS, patterns);
  }
  void add_extractors(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<DatetimeModelExtractor>>> extractors) {
    fbb_.AddOffset(DatetimeModel::VT_EXTRACTORS, extractors);
  }
  explicit DatetimeModelBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DatetimeModelBuilder &operator=(const DatetimeModelBuilder &);
  flatbuffers::Offset<DatetimeModel> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DatetimeModel>(end);
    return o;
  }
};

inline flatbuffers::Offset<DatetimeModel> CreateDatetimeModel(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> locales = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<DatetimeModelPattern>>> patterns = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<DatetimeModelExtractor>>> extractors = 0) {
  DatetimeModelBuilder builder_(_fbb);
  builder_.add_extractors(extractors);
  builder_.add_patterns(patterns);
  builder_.add_locales(locales);
  return builder_.Finish();
}

inline flatbuffers::Offset<DatetimeModel> CreateDatetimeModelDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *locales = nullptr,
    const std::vector<flatbuffers::Offset<DatetimeModelPattern>> *patterns = nullptr,
    const std::vector<flatbuffers::Offset<DatetimeModelExtractor>> *extractors = nullptr) {
  return libtextclassifier2::CreateDatetimeModel(
      _fbb,
      locales ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*locales) : 0,
      patterns ? _fbb.CreateVector<flatbuffers::Offset<DatetimeModelPattern>>(*patterns) : 0,
      extractors ? _fbb.CreateVector<flatbuffers::Offset<DatetimeModelExtractor>>(*extractors) : 0);
}

flatbuffers::Offset<DatetimeModel> CreateDatetimeModel(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct ModelTriggeringOptionsT : public flatbuffers::NativeTable {
  typedef ModelTriggeringOptions TableType;
  float min_annotate_confidence;
  ModelTriggeringOptionsT()
      : min_annotate_confidence(0.0f) {
  }
};

struct ModelTriggeringOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ModelTriggeringOptionsT NativeTableType;
  enum {
    VT_MIN_ANNOTATE_CONFIDENCE = 4
  };
  float min_annotate_confidence() const {
    return GetField<float>(VT_MIN_ANNOTATE_CONFIDENCE, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_MIN_ANNOTATE_CONFIDENCE) &&
           verifier.EndTable();
  }
  ModelTriggeringOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(ModelTriggeringOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<ModelTriggeringOptions> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ModelTriggeringOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct ModelTriggeringOptionsBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_min_annotate_confidence(float min_annotate_confidence) {
    fbb_.AddElement<float>(ModelTriggeringOptions::VT_MIN_ANNOTATE_CONFIDENCE, min_annotate_confidence, 0.0f);
  }
  explicit ModelTriggeringOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ModelTriggeringOptionsBuilder &operator=(const ModelTriggeringOptionsBuilder &);
  flatbuffers::Offset<ModelTriggeringOptions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ModelTriggeringOptions>(end);
    return o;
  }
};

inline flatbuffers::Offset<ModelTriggeringOptions> CreateModelTriggeringOptions(
    flatbuffers::FlatBufferBuilder &_fbb,
    float min_annotate_confidence = 0.0f) {
  ModelTriggeringOptionsBuilder builder_(_fbb);
  builder_.add_min_annotate_confidence(min_annotate_confidence);
  return builder_.Finish();
}

flatbuffers::Offset<ModelTriggeringOptions> CreateModelTriggeringOptions(flatbuffers::FlatBufferBuilder &_fbb, const ModelTriggeringOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct ModelT : public flatbuffers::NativeTable {
  typedef Model TableType;
  std::string locales;
  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<RegexModelT> regex_model;
  std::unique_ptr<SelectionModelOptionsT> selection_options;
  std::unique_ptr<ClassificationModelOptionsT> classification_options;
  std::unique_ptr<DatetimeModelT> datetime_model;
  std::unique_ptr<ModelTriggeringOptionsT> triggering_options;
  ModelT()
      : version(0) {
  }
};

struct Model FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ModelT NativeTableType;
  enum {
    VT_LOCALES = 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_MODEL = 18,
    VT_SELECTION_OPTIONS = 20,
    VT_CLASSIFICATION_OPTIONS = 22,
    VT_DATETIME_MODEL = 24,
    VT_TRIGGERING_OPTIONS = 26
  };
  const flatbuffers::String *locales() const {
    return GetPointer<const flatbuffers::String *>(VT_LOCALES);
  }
  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 RegexModel *regex_model() const {
    return GetPointer<const RegexModel *>(VT_REGEX_MODEL);
  }
  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 DatetimeModel *datetime_model() const {
    return GetPointer<const DatetimeModel *>(VT_DATETIME_MODEL);
  }
  const ModelTriggeringOptions *triggering_options() const {
    return GetPointer<const ModelTriggeringOptions *>(VT_TRIGGERING_OPTIONS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_LOCALES) &&
           verifier.Verify(locales()) &&
           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_MODEL) &&
           verifier.VerifyTable(regex_model()) &&
           VerifyOffset(verifier, VT_SELECTION_OPTIONS) &&
           verifier.VerifyTable(selection_options()) &&
           VerifyOffset(verifier, VT_CLASSIFICATION_OPTIONS) &&
           verifier.VerifyTable(classification_options()) &&
           VerifyOffset(verifier, VT_DATETIME_MODEL) &&
           verifier.VerifyTable(datetime_model()) &&
           VerifyOffset(verifier, VT_TRIGGERING_OPTIONS) &&
           verifier.VerifyTable(triggering_options()) &&
           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_locales(flatbuffers::Offset<flatbuffers::String> locales) {
    fbb_.AddOffset(Model::VT_LOCALES, locales);
  }
  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_model(flatbuffers::Offset<RegexModel> regex_model) {
    fbb_.AddOffset(Model::VT_REGEX_MODEL, regex_model);
  }
  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_datetime_model(flatbuffers::Offset<DatetimeModel> datetime_model) {
    fbb_.AddOffset(Model::VT_DATETIME_MODEL, datetime_model);
  }
  void add_triggering_options(flatbuffers::Offset<ModelTriggeringOptions> triggering_options) {
    fbb_.AddOffset(Model::VT_TRIGGERING_OPTIONS, triggering_options);
  }
  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> locales = 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<RegexModel> regex_model = 0,
    flatbuffers::Offset<SelectionModelOptions> selection_options = 0,
    flatbuffers::Offset<ClassificationModelOptions> classification_options = 0,
    flatbuffers::Offset<DatetimeModel> datetime_model = 0,
    flatbuffers::Offset<ModelTriggeringOptions> triggering_options = 0) {
  ModelBuilder builder_(_fbb);
  builder_.add_triggering_options(triggering_options);
  builder_.add_datetime_model(datetime_model);
  builder_.add_classification_options(classification_options);
  builder_.add_selection_options(selection_options);
  builder_.add_regex_model(regex_model);
  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_locales(locales);
  return builder_.Finish();
}

inline flatbuffers::Offset<Model> CreateModelDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *locales = 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<RegexModel> regex_model = 0,
    flatbuffers::Offset<SelectionModelOptions> selection_options = 0,
    flatbuffers::Offset<ClassificationModelOptions> classification_options = 0,
    flatbuffers::Offset<DatetimeModel> datetime_model = 0,
    flatbuffers::Offset<ModelTriggeringOptions> triggering_options = 0) {
  return libtextclassifier2::CreateModel(
      _fbb,
      locales ? _fbb.CreateString(locales) : 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_model,
      selection_options,
      classification_options,
      datetime_model,
      triggering_options);
}

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);

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 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);

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

struct AlternativeCollectionMapEntry FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AlternativeCollectionMapEntryT 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();
  }
  AlternativeCollectionMapEntryT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(AlternativeCollectionMapEntryT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<AlternativeCollectionMapEntry> Pack(flatbuffers::FlatBufferBuilder &_fbb, const AlternativeCollectionMapEntryT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

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

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

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

flatbuffers::Offset<AlternativeCollectionMapEntry> CreateAlternativeCollectionMapEntry(flatbuffers::FlatBufferBuilder &_fbb, const AlternativeCollectionMapEntryT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

}  // namespace FeatureProcessorOptions_

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;
  std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeaturesT> bounds_sensitive_features;
  std::vector<std::string> allowed_chargrams;
  bool tokenize_on_script_change;
  int32_t embedding_quantization_bits;
  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(true),
        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),
        tokenize_on_script_change(false),
        embedding_quantization_bits(8) {
  }
};

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_BOUNDS_SENSITIVE_FEATURES = 58,
    VT_ALLOWED_CHARGRAMS = 60,
    VT_TOKENIZE_ON_SCRIPT_CHANGE = 62,
    VT_EMBEDDING_QUANTIZATION_BITS = 64
  };
  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, 1) != 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);
  }
  const libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures *bounds_sensitive_features() const {
    return GetPointer<const libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures *>(VT_BOUNDS_SENSITIVE_FEATURES);
  }
  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;
  }
  int32_t embedding_quantization_bits() const {
    return GetField<int32_t>(VT_EMBEDDING_QUANTIZATION_BITS, 8);
  }
  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()) &&
           VerifyOffset(verifier, VT_BOUNDS_SENSITIVE_FEATURES) &&
           verifier.VerifyTable(bounds_sensitive_features()) &&
           VerifyOffset(verifier, VT_ALLOWED_CHARGRAMS) &&
           verifier.Verify(allowed_chargrams()) &&
           verifier.VerifyVectorOfStrings(allowed_chargrams()) &&
           VerifyField<uint8_t>(verifier, VT_TOKENIZE_ON_SCRIPT_CHANGE) &&
           VerifyField<int32_t>(verifier, VT_EMBEDDING_QUANTIZATION_BITS) &&
           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), 1);
  }
  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_bounds_sensitive_features(flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures> bounds_sensitive_features) {
    fbb_.AddOffset(FeatureProcessorOptions::VT_BOUNDS_SENSITIVE_FEATURES, bounds_sensitive_features);
  }
  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);
  }
  void add_embedding_quantization_bits(int32_t embedding_quantization_bits) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_EMBEDDING_QUANTIZATION_BITS, embedding_quantization_bits, 8);
  }
  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 = true,
    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,
    flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures> bounds_sensitive_features = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> allowed_chargrams = 0,
    bool tokenize_on_script_change = false,
    int32_t embedding_quantization_bits = 8) {
  FeatureProcessorOptionsBuilder builder_(_fbb);
  builder_.add_embedding_quantization_bits(embedding_quantization_bits);
  builder_.add_allowed_chargrams(allowed_chargrams);
  builder_.add_bounds_sensitive_features(bounds_sensitive_features);
  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_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 = true,
    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,
    flatbuffers::Offset<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeatures> bounds_sensitive_features = 0,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *allowed_chargrams = nullptr,
    bool tokenize_on_script_change = false,
    int32_t embedding_quantization_bits = 8) {
  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,
      bounds_sensitive_features,
      allowed_chargrams ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*allowed_chargrams) : 0,
      tokenize_on_script_change,
      embedding_quantization_bits);
}

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

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; };
  { auto _e = batch_size(); _o->batch_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;
  auto _batch_size = _o->batch_size;
  return libtextclassifier2::CreateSelectionModelOptions(
      _fbb,
      _strip_unpaired_brackets,
      _symmetry_context_size,
      _batch_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);
}

namespace RegexModel_ {

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(); };
  { auto _e = enabled_for_annotation(); _o->enabled_for_annotation = _e; };
  { auto _e = enabled_for_classification(); _o->enabled_for_classification = _e; };
  { auto _e = enabled_for_selection(); _o->enabled_for_selection = _e; };
  { auto _e = target_classification_score(); _o->target_classification_score = _e; };
  { auto _e = priority_score(); _o->priority_score = _e; };
}

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);
  auto _enabled_for_annotation = _o->enabled_for_annotation;
  auto _enabled_for_classification = _o->enabled_for_classification;
  auto _enabled_for_selection = _o->enabled_for_selection;
  auto _target_classification_score = _o->target_classification_score;
  auto _priority_score = _o->priority_score;
  return libtextclassifier2::RegexModel_::CreatePattern(
      _fbb,
      _collection_name,
      _pattern,
      _enabled_for_annotation,
      _enabled_for_classification,
      _enabled_for_selection,
      _target_classification_score,
      _priority_score);
}

}  // namespace RegexModel_

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

inline void RegexModel::UnPackTo(RegexModelT *_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::RegexModel_::PatternT>(_e->Get(_i)->UnPack(_resolver)); } } };
}

inline flatbuffers::Offset<RegexModel> RegexModel::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegexModelT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateRegexModel(_fbb, _o, _rehasher);
}

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

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

inline void DatetimeModelPattern::UnPackTo(DatetimeModelPatternT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = regexes(); if (_e) { _o->regexes.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->regexes[_i] = _e->Get(_i)->str(); } } };
  { auto _e = locales(); if (_e) { _o->locales.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->locales[_i] = _e->Get(_i); } } };
  { auto _e = target_classification_score(); _o->target_classification_score = _e; };
  { auto _e = priority_score(); _o->priority_score = _e; };
}

inline flatbuffers::Offset<DatetimeModelPattern> DatetimeModelPattern::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelPatternT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateDatetimeModelPattern(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<DatetimeModelPattern> CreateDatetimeModelPattern(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelPatternT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DatetimeModelPatternT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _regexes = _o->regexes.size() ? _fbb.CreateVectorOfStrings(_o->regexes) : 0;
  auto _locales = _o->locales.size() ? _fbb.CreateVector(_o->locales) : 0;
  auto _target_classification_score = _o->target_classification_score;
  auto _priority_score = _o->priority_score;
  return libtextclassifier2::CreateDatetimeModelPattern(
      _fbb,
      _regexes,
      _locales,
      _target_classification_score,
      _priority_score);
}

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

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

inline flatbuffers::Offset<DatetimeModelExtractor> DatetimeModelExtractor::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelExtractorT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateDatetimeModelExtractor(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<DatetimeModelExtractor> CreateDatetimeModelExtractor(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelExtractorT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DatetimeModelExtractorT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _extractor = _o->extractor;
  auto _pattern = _o->pattern.empty() ? 0 : _fbb.CreateString(_o->pattern);
  auto _locales = _o->locales.size() ? _fbb.CreateVector(_o->locales) : 0;
  return libtextclassifier2::CreateDatetimeModelExtractor(
      _fbb,
      _extractor,
      _pattern,
      _locales);
}

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

inline void DatetimeModel::UnPackTo(DatetimeModelT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = locales(); if (_e) { _o->locales.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->locales[_i] = _e->Get(_i)->str(); } } };
  { 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<DatetimeModelPatternT>(_e->Get(_i)->UnPack(_resolver)); } } };
  { auto _e = extractors(); if (_e) { _o->extractors.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->extractors[_i] = std::unique_ptr<DatetimeModelExtractorT>(_e->Get(_i)->UnPack(_resolver)); } } };
}

inline flatbuffers::Offset<DatetimeModel> DatetimeModel::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateDatetimeModel(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<DatetimeModel> CreateDatetimeModel(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DatetimeModelT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _locales = _o->locales.size() ? _fbb.CreateVectorOfStrings(_o->locales) : 0;
  auto _patterns = _o->patterns.size() ? _fbb.CreateVector<flatbuffers::Offset<DatetimeModelPattern>> (_o->patterns.size(), [](size_t i, _VectorArgs *__va) { return CreateDatetimeModelPattern(*__va->__fbb, __va->__o->patterns[i].get(), __va->__rehasher); }, &_va ) : 0;
  auto _extractors = _o->extractors.size() ? _fbb.CreateVector<flatbuffers::Offset<DatetimeModelExtractor>> (_o->extractors.size(), [](size_t i, _VectorArgs *__va) { return CreateDatetimeModelExtractor(*__va->__fbb, __va->__o->extractors[i].get(), __va->__rehasher); }, &_va ) : 0;
  return libtextclassifier2::CreateDatetimeModel(
      _fbb,
      _locales,
      _patterns,
      _extractors);
}

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

inline void ModelTriggeringOptions::UnPackTo(ModelTriggeringOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = min_annotate_confidence(); _o->min_annotate_confidence = _e; };
}

inline flatbuffers::Offset<ModelTriggeringOptions> ModelTriggeringOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ModelTriggeringOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateModelTriggeringOptions(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<ModelTriggeringOptions> CreateModelTriggeringOptions(flatbuffers::FlatBufferBuilder &_fbb, const ModelTriggeringOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ModelTriggeringOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _min_annotate_confidence = _o->min_annotate_confidence;
  return libtextclassifier2::CreateModelTriggeringOptions(
      _fbb,
      _min_annotate_confidence);
}

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 = locales(); if (_e) _o->locales = _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_model(); if (_e) _o->regex_model = std::unique_ptr<RegexModelT>(_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 = datetime_model(); if (_e) _o->datetime_model = std::unique_ptr<DatetimeModelT>(_e->UnPack(_resolver)); };
  { auto _e = triggering_options(); if (_e) _o->triggering_options = std::unique_ptr<ModelTriggeringOptionsT>(_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 _locales = _o->locales.empty() ? 0 : _fbb.CreateString(_o->locales);
  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_model = _o->regex_model ? CreateRegexModel(_fbb, _o->regex_model.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 _datetime_model = _o->datetime_model ? CreateDatetimeModel(_fbb, _o->datetime_model.get(), _rehasher) : 0;
  auto _triggering_options = _o->triggering_options ? CreateModelTriggeringOptions(_fbb, _o->triggering_options.get(), _rehasher) : 0;
  return libtextclassifier2::CreateModel(
      _fbb,
      _locales,
      _version,
      _selection_feature_options,
      _classification_feature_options,
      _selection_model,
      _classification_model,
      _embedding_model,
      _regex_model,
      _selection_options,
      _classification_options,
      _datetime_model,
      _triggering_options);
}

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);
}

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 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);
}

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

inline void AlternativeCollectionMapEntry::UnPackTo(AlternativeCollectionMapEntryT *_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<AlternativeCollectionMapEntry> AlternativeCollectionMapEntry::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AlternativeCollectionMapEntryT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateAlternativeCollectionMapEntry(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<AlternativeCollectionMapEntry> CreateAlternativeCollectionMapEntry(flatbuffers::FlatBufferBuilder &_fbb, const AlternativeCollectionMapEntryT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AlternativeCollectionMapEntryT* __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_::CreateAlternativeCollectionMapEntry(
      _fbb,
      _key,
      _value);
}

}  // namespace FeatureProcessorOptions_

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 = bounds_sensitive_features(); if (_e) _o->bounds_sensitive_features = std::unique_ptr<libtextclassifier2::FeatureProcessorOptions_::BoundsSensitiveFeaturesT>(_e->UnPack(_resolver)); };
  { 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; };
  { auto _e = embedding_quantization_bits(); _o->embedding_quantization_bits = _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 _bounds_sensitive_features = _o->bounds_sensitive_features ? CreateBoundsSensitiveFeatures(_fbb, _o->bounds_sensitive_features.get(), _rehasher) : 0;
  auto _allowed_chargrams = _o->allowed_chargrams.size() ? _fbb.CreateVectorOfStrings(_o->allowed_chargrams) : 0;
  auto _tokenize_on_script_change = _o->tokenize_on_script_change;
  auto _embedding_quantization_bits = _o->embedding_quantization_bits;
  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,
      _bounds_sensitive_features,
      _allowed_chargrams,
      _tokenize_on_script_change,
      _embedding_quantization_bits);
}

inline const libtextclassifier2::Model *GetModel(const void *buf) {
  return flatbuffers::GetRoot<libtextclassifier2::Model>(buf);
}

inline const char *ModelIdentifier() {
  return "TC2 ";
}

inline bool ModelBufferHasIdentifier(const void *buf) {
  return flatbuffers::BufferHasIdentifier(
      buf, ModelIdentifier());
}

inline bool VerifyModelBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<libtextclassifier2::Model>(ModelIdentifier());
}

inline void FinishModelBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<libtextclassifier2::Model> root) {
  fbb.Finish(root, ModelIdentifier());
}

inline std::unique_ptr<ModelT> UnPackModel(
    const void *buf,
    const flatbuffers::resolver_function_t *res = nullptr) {
  return std::unique_ptr<ModelT>(GetModel(buf)->UnPack(res));
}

}  // namespace libtextclassifier2

#endif  // FLATBUFFERS_GENERATED_MODEL_LIBTEXTCLASSIFIER2_H_
