/*
 * 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 CompressedBuffer;
struct CompressedBufferT;

struct SelectionModelOptions;
struct SelectionModelOptionsT;

struct ClassificationModelOptions;
struct ClassificationModelOptionsT;

namespace RegexModel_ {

struct Pattern;
struct PatternT;

}  // namespace RegexModel_

struct RegexModel;
struct RegexModelT;

namespace DatetimeModelPattern_ {

struct Regex;
struct RegexT;

}  // namespace DatetimeModelPattern_

struct DatetimeModelPattern;
struct DatetimeModelPatternT;

struct DatetimeModelExtractor;
struct DatetimeModelExtractorT;

struct DatetimeModel;
struct DatetimeModelT;

namespace DatetimeModelLibrary_ {

struct Item;
struct ItemT;

}  // namespace DatetimeModelLibrary_

struct DatetimeModelLibrary;
struct DatetimeModelLibraryT;

struct ModelTriggeringOptions;
struct ModelTriggeringOptionsT;

struct OutputOptions;
struct OutputOptionsT;

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 ModeFlag {
  ModeFlag_NONE = 0,
  ModeFlag_ANNOTATION = 1,
  ModeFlag_CLASSIFICATION = 2,
  ModeFlag_ANNOTATION_AND_CLASSIFICATION = 3,
  ModeFlag_SELECTION = 4,
  ModeFlag_ANNOTATION_AND_SELECTION = 5,
  ModeFlag_CLASSIFICATION_AND_SELECTION = 6,
  ModeFlag_ALL = 7,
  ModeFlag_MIN = ModeFlag_NONE,
  ModeFlag_MAX = ModeFlag_ALL
};

inline ModeFlag (&EnumValuesModeFlag())[8] {
  static ModeFlag values[] = {
    ModeFlag_NONE,
    ModeFlag_ANNOTATION,
    ModeFlag_CLASSIFICATION,
    ModeFlag_ANNOTATION_AND_CLASSIFICATION,
    ModeFlag_SELECTION,
    ModeFlag_ANNOTATION_AND_SELECTION,
    ModeFlag_CLASSIFICATION_AND_SELECTION,
    ModeFlag_ALL
  };
  return values;
}

inline const char **EnumNamesModeFlag() {
  static const char *names[] = {
    "NONE",
    "ANNOTATION",
    "CLASSIFICATION",
    "ANNOTATION_AND_CLASSIFICATION",
    "SELECTION",
    "ANNOTATION_AND_SELECTION",
    "CLASSIFICATION_AND_SELECTION",
    "ALL",
    nullptr
  };
  return names;
}

inline const char *EnumNameModeFlag(ModeFlag e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesModeFlag()[index];
}

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

enum DatetimeGroupType {
  DatetimeGroupType_GROUP_UNKNOWN = 0,
  DatetimeGroupType_GROUP_UNUSED = 1,
  DatetimeGroupType_GROUP_YEAR = 2,
  DatetimeGroupType_GROUP_MONTH = 3,
  DatetimeGroupType_GROUP_DAY = 4,
  DatetimeGroupType_GROUP_HOUR = 5,
  DatetimeGroupType_GROUP_MINUTE = 6,
  DatetimeGroupType_GROUP_SECOND = 7,
  DatetimeGroupType_GROUP_AMPM = 8,
  DatetimeGroupType_GROUP_RELATIONDISTANCE = 9,
  DatetimeGroupType_GROUP_RELATION = 10,
  DatetimeGroupType_GROUP_RELATIONTYPE = 11,
  DatetimeGroupType_GROUP_DUMMY1 = 12,
  DatetimeGroupType_GROUP_DUMMY2 = 13,
  DatetimeGroupType_MIN = DatetimeGroupType_GROUP_UNKNOWN,
  DatetimeGroupType_MAX = DatetimeGroupType_GROUP_DUMMY2
};

inline DatetimeGroupType (&EnumValuesDatetimeGroupType())[14] {
  static DatetimeGroupType values[] = {
    DatetimeGroupType_GROUP_UNKNOWN,
    DatetimeGroupType_GROUP_UNUSED,
    DatetimeGroupType_GROUP_YEAR,
    DatetimeGroupType_GROUP_MONTH,
    DatetimeGroupType_GROUP_DAY,
    DatetimeGroupType_GROUP_HOUR,
    DatetimeGroupType_GROUP_MINUTE,
    DatetimeGroupType_GROUP_SECOND,
    DatetimeGroupType_GROUP_AMPM,
    DatetimeGroupType_GROUP_RELATIONDISTANCE,
    DatetimeGroupType_GROUP_RELATION,
    DatetimeGroupType_GROUP_RELATIONTYPE,
    DatetimeGroupType_GROUP_DUMMY1,
    DatetimeGroupType_GROUP_DUMMY2
  };
  return values;
}

inline const char **EnumNamesDatetimeGroupType() {
  static const char *names[] = {
    "GROUP_UNKNOWN",
    "GROUP_UNUSED",
    "GROUP_YEAR",
    "GROUP_MONTH",
    "GROUP_DAY",
    "GROUP_HOUR",
    "GROUP_MINUTE",
    "GROUP_SECOND",
    "GROUP_AMPM",
    "GROUP_RELATIONDISTANCE",
    "GROUP_RELATION",
    "GROUP_RELATIONTYPE",
    "GROUP_DUMMY1",
    "GROUP_DUMMY2",
    nullptr
  };
  return names;
}

inline const char *EnumNameDatetimeGroupType(DatetimeGroupType e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesDatetimeGroupType()[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 CompressedBufferT : public flatbuffers::NativeTable {
  typedef CompressedBuffer TableType;
  std::vector<uint8_t> buffer;
  int32_t uncompressed_size;
  CompressedBufferT()
      : uncompressed_size(0) {
  }
};

struct CompressedBuffer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef CompressedBufferT NativeTableType;
  enum {
    VT_BUFFER = 4,
    VT_UNCOMPRESSED_SIZE = 6
  };
  const flatbuffers::Vector<uint8_t> *buffer() const {
    return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_BUFFER);
  }
  int32_t uncompressed_size() const {
    return GetField<int32_t>(VT_UNCOMPRESSED_SIZE, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_BUFFER) &&
           verifier.Verify(buffer()) &&
           VerifyField<int32_t>(verifier, VT_UNCOMPRESSED_SIZE) &&
           verifier.EndTable();
  }
  CompressedBufferT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(CompressedBufferT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<CompressedBuffer> Pack(flatbuffers::FlatBufferBuilder &_fbb, const CompressedBufferT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct CompressedBufferBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_buffer(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> buffer) {
    fbb_.AddOffset(CompressedBuffer::VT_BUFFER, buffer);
  }
  void add_uncompressed_size(int32_t uncompressed_size) {
    fbb_.AddElement<int32_t>(CompressedBuffer::VT_UNCOMPRESSED_SIZE, uncompressed_size, 0);
  }
  explicit CompressedBufferBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  CompressedBufferBuilder &operator=(const CompressedBufferBuilder &);
  flatbuffers::Offset<CompressedBuffer> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CompressedBuffer>(end);
    return o;
  }
};

inline flatbuffers::Offset<CompressedBuffer> CreateCompressedBuffer(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<uint8_t>> buffer = 0,
    int32_t uncompressed_size = 0) {
  CompressedBufferBuilder builder_(_fbb);
  builder_.add_uncompressed_size(uncompressed_size);
  builder_.add_buffer(buffer);
  return builder_.Finish();
}

inline flatbuffers::Offset<CompressedBuffer> CreateCompressedBufferDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<uint8_t> *buffer = nullptr,
    int32_t uncompressed_size = 0) {
  return libtextclassifier2::CreateCompressedBuffer(
      _fbb,
      buffer ? _fbb.CreateVector<uint8_t>(*buffer) : 0,
      uncompressed_size);
}

flatbuffers::Offset<CompressedBuffer> CreateCompressedBuffer(flatbuffers::FlatBufferBuilder &_fbb, const CompressedBufferT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

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

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,
    VT_ALWAYS_CLASSIFY_SUGGESTED_SELECTION = 10
  };
  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 always_classify_suggested_selection() const {
    return GetField<uint8_t>(VT_ALWAYS_CLASSIFY_SUGGESTED_SELECTION, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_STRIP_UNPAIRED_BRACKETS) &&
           VerifyField<int32_t>(verifier, VT_SYMMETRY_CONTEXT_SIZE) &&
           VerifyField<int32_t>(verifier, VT_BATCH_SIZE) &&
           VerifyField<uint8_t>(verifier, VT_ALWAYS_CLASSIFY_SUGGESTED_SELECTION) &&
           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);
  }
  void add_always_classify_suggested_selection(bool always_classify_suggested_selection) {
    fbb_.AddElement<uint8_t>(SelectionModelOptions::VT_ALWAYS_CLASSIFY_SUGGESTED_SELECTION, static_cast<uint8_t>(always_classify_suggested_selection), 0);
  }
  explicit SelectionModelOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SelectionModelOptionsBuilder &operator=(const SelectionModelOptionsBuilder &);
  flatbuffers::Offset<SelectionModelOptions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SelectionModelOptions>(end);
    return o;
  }
};

inline flatbuffers::Offset<SelectionModelOptions> CreateSelectionModelOptions(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool strip_unpaired_brackets = true,
    int32_t symmetry_context_size = 0,
    int32_t batch_size = 1024,
    bool always_classify_suggested_selection = false) {
  SelectionModelOptionsBuilder builder_(_fbb);
  builder_.add_batch_size(batch_size);
  builder_.add_symmetry_context_size(symmetry_context_size);
  builder_.add_always_classify_suggested_selection(always_classify_suggested_selection);
  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;
  int32_t address_min_num_tokens;
  int32_t max_num_tokens;
  ClassificationModelOptionsT()
      : phone_min_num_digits(7),
        phone_max_num_digits(15),
        address_min_num_tokens(0),
        max_num_tokens(-1) {
  }
};

struct ClassificationModelOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ClassificationModelOptionsT NativeTableType;
  enum {
    VT_PHONE_MIN_NUM_DIGITS = 4,
    VT_PHONE_MAX_NUM_DIGITS = 6,
    VT_ADDRESS_MIN_NUM_TOKENS = 8,
    VT_MAX_NUM_TOKENS = 10
  };
  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);
  }
  int32_t address_min_num_tokens() const {
    return GetField<int32_t>(VT_ADDRESS_MIN_NUM_TOKENS, 0);
  }
  int32_t max_num_tokens() const {
    return GetField<int32_t>(VT_MAX_NUM_TOKENS, -1);
  }
  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) &&
           VerifyField<int32_t>(verifier, VT_ADDRESS_MIN_NUM_TOKENS) &&
           VerifyField<int32_t>(verifier, VT_MAX_NUM_TOKENS) &&
           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);
  }
  void add_address_min_num_tokens(int32_t address_min_num_tokens) {
    fbb_.AddElement<int32_t>(ClassificationModelOptions::VT_ADDRESS_MIN_NUM_TOKENS, address_min_num_tokens, 0);
  }
  void add_max_num_tokens(int32_t max_num_tokens) {
    fbb_.AddElement<int32_t>(ClassificationModelOptions::VT_MAX_NUM_TOKENS, max_num_tokens, -1);
  }
  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,
    int32_t address_min_num_tokens = 0,
    int32_t max_num_tokens = -1) {
  ClassificationModelOptionsBuilder builder_(_fbb);
  builder_.add_max_num_tokens(max_num_tokens);
  builder_.add_address_min_num_tokens(address_min_num_tokens);
  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;
  libtextclassifier2::ModeFlag enabled_modes;
  float target_classification_score;
  float priority_score;
  bool use_approximate_matching;
  std::unique_ptr<libtextclassifier2::CompressedBufferT> compressed_pattern;
  PatternT()
      : enabled_modes(libtextclassifier2::ModeFlag_ALL),
        target_classification_score(1.0f),
        priority_score(0.0f),
        use_approximate_matching(false) {
  }
};

struct Pattern FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef PatternT NativeTableType;
  enum {
    VT_COLLECTION_NAME = 4,
    VT_PATTERN = 6,
    VT_ENABLED_MODES = 8,
    VT_TARGET_CLASSIFICATION_SCORE = 10,
    VT_PRIORITY_SCORE = 12,
    VT_USE_APPROXIMATE_MATCHING = 14,
    VT_COMPRESSED_PATTERN = 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);
  }
  libtextclassifier2::ModeFlag enabled_modes() const {
    return static_cast<libtextclassifier2::ModeFlag>(GetField<int32_t>(VT_ENABLED_MODES, 7));
  }
  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 use_approximate_matching() const {
    return GetField<uint8_t>(VT_USE_APPROXIMATE_MATCHING, 0) != 0;
  }
  const libtextclassifier2::CompressedBuffer *compressed_pattern() const {
    return GetPointer<const libtextclassifier2::CompressedBuffer *>(VT_COMPRESSED_PATTERN);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_COLLECTION_NAME) &&
           verifier.Verify(collection_name()) &&
           VerifyOffset(verifier, VT_PATTERN) &&
           verifier.Verify(pattern()) &&
           VerifyField<int32_t>(verifier, VT_ENABLED_MODES) &&
           VerifyField<float>(verifier, VT_TARGET_CLASSIFICATION_SCORE) &&
           VerifyField<float>(verifier, VT_PRIORITY_SCORE) &&
           VerifyField<uint8_t>(verifier, VT_USE_APPROXIMATE_MATCHING) &&
           VerifyOffset(verifier, VT_COMPRESSED_PATTERN) &&
           verifier.VerifyTable(compressed_pattern()) &&
           verifier.EndTable();
  }
  PatternT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(PatternT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<Pattern> Pack(flatbuffers::FlatBufferBuilder &_fbb, const PatternT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct PatternBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_collection_name(flatbuffers::Offset<flatbuffers::String> collection_name) {
    fbb_.AddOffset(Pattern::VT_COLLECTION_NAME, collection_name);
  }
  void add_pattern(flatbuffers::Offset<flatbuffers::String> pattern) {
    fbb_.AddOffset(Pattern::VT_PATTERN, pattern);
  }
  void add_enabled_modes(libtextclassifier2::ModeFlag enabled_modes) {
    fbb_.AddElement<int32_t>(Pattern::VT_ENABLED_MODES, static_cast<int32_t>(enabled_modes), 7);
  }
  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);
  }
  void add_use_approximate_matching(bool use_approximate_matching) {
    fbb_.AddElement<uint8_t>(Pattern::VT_USE_APPROXIMATE_MATCHING, static_cast<uint8_t>(use_approximate_matching), 0);
  }
  void add_compressed_pattern(flatbuffers::Offset<libtextclassifier2::CompressedBuffer> compressed_pattern) {
    fbb_.AddOffset(Pattern::VT_COMPRESSED_PATTERN, compressed_pattern);
  }
  explicit PatternBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PatternBuilder &operator=(const PatternBuilder &);
  flatbuffers::Offset<Pattern> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Pattern>(end);
    return o;
  }
};

inline flatbuffers::Offset<Pattern> CreatePattern(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> collection_name = 0,
    flatbuffers::Offset<flatbuffers::String> pattern = 0,
    libtextclassifier2::ModeFlag enabled_modes = libtextclassifier2::ModeFlag_ALL,
    float target_classification_score = 1.0f,
    float priority_score = 0.0f,
    bool use_approximate_matching = false,
    flatbuffers::Offset<libtextclassifier2::CompressedBuffer> compressed_pattern = 0) {
  PatternBuilder builder_(_fbb);
  builder_.add_compressed_pattern(compressed_pattern);
  builder_.add_priority_score(priority_score);
  builder_.add_target_classification_score(target_classification_score);
  builder_.add_enabled_modes(enabled_modes);
  builder_.add_pattern(pattern);
  builder_.add_collection_name(collection_name);
  builder_.add_use_approximate_matching(use_approximate_matching);
  return builder_.Finish();
}

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

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

namespace DatetimeModelPattern_ {

struct RegexT : public flatbuffers::NativeTable {
  typedef Regex TableType;
  std::string pattern;
  std::vector<libtextclassifier2::DatetimeGroupType> groups;
  std::unique_ptr<libtextclassifier2::CompressedBufferT> compressed_pattern;
  RegexT() {
  }
};

struct Regex FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef RegexT NativeTableType;
  enum {
    VT_PATTERN = 4,
    VT_GROUPS = 6,
    VT_COMPRESSED_PATTERN = 8
  };
  const flatbuffers::String *pattern() const {
    return GetPointer<const flatbuffers::String *>(VT_PATTERN);
  }
  const flatbuffers::Vector<int32_t> *groups() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_GROUPS);
  }
  const libtextclassifier2::CompressedBuffer *compressed_pattern() const {
    return GetPointer<const libtextclassifier2::CompressedBuffer *>(VT_COMPRESSED_PATTERN);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_PATTERN) &&
           verifier.Verify(pattern()) &&
           VerifyOffset(verifier, VT_GROUPS) &&
           verifier.Verify(groups()) &&
           VerifyOffset(verifier, VT_COMPRESSED_PATTERN) &&
           verifier.VerifyTable(compressed_pattern()) &&
           verifier.EndTable();
  }
  RegexT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(RegexT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<Regex> Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegexT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct RegexBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_pattern(flatbuffers::Offset<flatbuffers::String> pattern) {
    fbb_.AddOffset(Regex::VT_PATTERN, pattern);
  }
  void add_groups(flatbuffers::Offset<flatbuffers::Vector<int32_t>> groups) {
    fbb_.AddOffset(Regex::VT_GROUPS, groups);
  }
  void add_compressed_pattern(flatbuffers::Offset<libtextclassifier2::CompressedBuffer> compressed_pattern) {
    fbb_.AddOffset(Regex::VT_COMPRESSED_PATTERN, compressed_pattern);
  }
  explicit RegexBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RegexBuilder &operator=(const RegexBuilder &);
  flatbuffers::Offset<Regex> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Regex>(end);
    return o;
  }
};

inline flatbuffers::Offset<Regex> CreateRegex(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> pattern = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> groups = 0,
    flatbuffers::Offset<libtextclassifier2::CompressedBuffer> compressed_pattern = 0) {
  RegexBuilder builder_(_fbb);
  builder_.add_compressed_pattern(compressed_pattern);
  builder_.add_groups(groups);
  builder_.add_pattern(pattern);
  return builder_.Finish();
}

inline flatbuffers::Offset<Regex> CreateRegexDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *pattern = nullptr,
    const std::vector<int32_t> *groups = nullptr,
    flatbuffers::Offset<libtextclassifier2::CompressedBuffer> compressed_pattern = 0) {
  return libtextclassifier2::DatetimeModelPattern_::CreateRegex(
      _fbb,
      pattern ? _fbb.CreateString(pattern) : 0,
      groups ? _fbb.CreateVector<int32_t>(*groups) : 0,
      compressed_pattern);
}

flatbuffers::Offset<Regex> CreateRegex(flatbuffers::FlatBufferBuilder &_fbb, const RegexT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

}  // namespace DatetimeModelPattern_

struct DatetimeModelPatternT : public flatbuffers::NativeTable {
  typedef DatetimeModelPattern TableType;
  std::vector<std::unique_ptr<libtextclassifier2::DatetimeModelPattern_::RegexT>> regexes;
  std::vector<int32_t> locales;
  float target_classification_score;
  float priority_score;
  ModeFlag enabled_modes;
  DatetimeModelPatternT()
      : target_classification_score(1.0f),
        priority_score(0.0f),
        enabled_modes(ModeFlag_ALL) {
  }
};

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,
    VT_ENABLED_MODES = 12
  };
  const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::DatetimeModelPattern_::Regex>> *regexes() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::DatetimeModelPattern_::Regex>> *>(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);
  }
  ModeFlag enabled_modes() const {
    return static_cast<ModeFlag>(GetField<int32_t>(VT_ENABLED_MODES, 7));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_REGEXES) &&
           verifier.Verify(regexes()) &&
           verifier.VerifyVectorOfTables(regexes()) &&
           VerifyOffset(verifier, VT_LOCALES) &&
           verifier.Verify(locales()) &&
           VerifyField<float>(verifier, VT_TARGET_CLASSIFICATION_SCORE) &&
           VerifyField<float>(verifier, VT_PRIORITY_SCORE) &&
           VerifyField<int32_t>(verifier, VT_ENABLED_MODES) &&
           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<libtextclassifier2::DatetimeModelPattern_::Regex>>> 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);
  }
  void add_enabled_modes(ModeFlag enabled_modes) {
    fbb_.AddElement<int32_t>(DatetimeModelPattern::VT_ENABLED_MODES, static_cast<int32_t>(enabled_modes), 7);
  }
  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<libtextclassifier2::DatetimeModelPattern_::Regex>>> regexes = 0,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> locales = 0,
    float target_classification_score = 1.0f,
    float priority_score = 0.0f,
    ModeFlag enabled_modes = ModeFlag_ALL) {
  DatetimeModelPatternBuilder builder_(_fbb);
  builder_.add_enabled_modes(enabled_modes);
  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<libtextclassifier2::DatetimeModelPattern_::Regex>> *regexes = nullptr,
    const std::vector<int32_t> *locales = nullptr,
    float target_classification_score = 1.0f,
    float priority_score = 0.0f,
    ModeFlag enabled_modes = ModeFlag_ALL) {
  return libtextclassifier2::CreateDatetimeModelPattern(
      _fbb,
      regexes ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::DatetimeModelPattern_::Regex>>(*regexes) : 0,
      locales ? _fbb.CreateVector<int32_t>(*locales) : 0,
      target_classification_score,
      priority_score,
      enabled_modes);
}

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;
  std::unique_ptr<CompressedBufferT> compressed_pattern;
  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,
    VT_COMPRESSED_PATTERN = 10
  };
  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);
  }
  const CompressedBuffer *compressed_pattern() const {
    return GetPointer<const CompressedBuffer *>(VT_COMPRESSED_PATTERN);
  }
  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()) &&
           VerifyOffset(verifier, VT_COMPRESSED_PATTERN) &&
           verifier.VerifyTable(compressed_pattern()) &&
           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);
  }
  void add_compressed_pattern(flatbuffers::Offset<CompressedBuffer> compressed_pattern) {
    fbb_.AddOffset(DatetimeModelExtractor::VT_COMPRESSED_PATTERN, compressed_pattern);
  }
  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,
    flatbuffers::Offset<CompressedBuffer> compressed_pattern = 0) {
  DatetimeModelExtractorBuilder builder_(_fbb);
  builder_.add_compressed_pattern(compressed_pattern);
  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,
    flatbuffers::Offset<CompressedBuffer> compressed_pattern = 0) {
  return libtextclassifier2::CreateDatetimeModelExtractor(
      _fbb,
      extractor,
      pattern ? _fbb.CreateString(pattern) : 0,
      locales ? _fbb.CreateVector<int32_t>(*locales) : 0,
      compressed_pattern);
}

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;
  bool use_extractors_for_locating;
  std::vector<int32_t> default_locales;
  DatetimeModelT()
      : use_extractors_for_locating(true) {
  }
};

struct DatetimeModel FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef DatetimeModelT NativeTableType;
  enum {
    VT_LOCALES = 4,
    VT_PATTERNS = 6,
    VT_EXTRACTORS = 8,
    VT_USE_EXTRACTORS_FOR_LOCATING = 10,
    VT_DEFAULT_LOCALES = 12
  };
  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 use_extractors_for_locating() const {
    return GetField<uint8_t>(VT_USE_EXTRACTORS_FOR_LOCATING, 1) != 0;
  }
  const flatbuffers::Vector<int32_t> *default_locales() const {
    return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_DEFAULT_LOCALES);
  }
  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()) &&
           VerifyField<uint8_t>(verifier, VT_USE_EXTRACTORS_FOR_LOCATING) &&
           VerifyOffset(verifier, VT_DEFAULT_LOCALES) &&
           verifier.Verify(default_locales()) &&
           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);
  }
  void add_use_extractors_for_locating(bool use_extractors_for_locating) {
    fbb_.AddElement<uint8_t>(DatetimeModel::VT_USE_EXTRACTORS_FOR_LOCATING, static_cast<uint8_t>(use_extractors_for_locating), 1);
  }
  void add_default_locales(flatbuffers::Offset<flatbuffers::Vector<int32_t>> default_locales) {
    fbb_.AddOffset(DatetimeModel::VT_DEFAULT_LOCALES, default_locales);
  }
  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,
    bool use_extractors_for_locating = true,
    flatbuffers::Offset<flatbuffers::Vector<int32_t>> default_locales = 0) {
  DatetimeModelBuilder builder_(_fbb);
  builder_.add_default_locales(default_locales);
  builder_.add_extractors(extractors);
  builder_.add_patterns(patterns);
  builder_.add_locales(locales);
  builder_.add_use_extractors_for_locating(use_extractors_for_locating);
  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,
    bool use_extractors_for_locating = true,
    const std::vector<int32_t> *default_locales = 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,
      use_extractors_for_locating,
      default_locales ? _fbb.CreateVector<int32_t>(*default_locales) : 0);
}

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

namespace DatetimeModelLibrary_ {

struct ItemT : public flatbuffers::NativeTable {
  typedef Item TableType;
  std::string key;
  std::unique_ptr<libtextclassifier2::DatetimeModelT> value;
  ItemT() {
  }
};

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

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

inline flatbuffers::Offset<Item> CreateItem(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> key = 0,
    flatbuffers::Offset<libtextclassifier2::DatetimeModel> value = 0) {
  ItemBuilder builder_(_fbb);
  builder_.add_value(value);
  builder_.add_key(key);
  return builder_.Finish();
}

inline flatbuffers::Offset<Item> CreateItemDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *key = nullptr,
    flatbuffers::Offset<libtextclassifier2::DatetimeModel> value = 0) {
  return libtextclassifier2::DatetimeModelLibrary_::CreateItem(
      _fbb,
      key ? _fbb.CreateString(key) : 0,
      value);
}

flatbuffers::Offset<Item> CreateItem(flatbuffers::FlatBufferBuilder &_fbb, const ItemT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

}  // namespace DatetimeModelLibrary_

struct DatetimeModelLibraryT : public flatbuffers::NativeTable {
  typedef DatetimeModelLibrary TableType;
  std::vector<std::unique_ptr<libtextclassifier2::DatetimeModelLibrary_::ItemT>> models;
  DatetimeModelLibraryT() {
  }
};

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

struct DatetimeModelLibraryBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_models(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::DatetimeModelLibrary_::Item>>> models) {
    fbb_.AddOffset(DatetimeModelLibrary::VT_MODELS, models);
  }
  explicit DatetimeModelLibraryBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DatetimeModelLibraryBuilder &operator=(const DatetimeModelLibraryBuilder &);
  flatbuffers::Offset<DatetimeModelLibrary> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DatetimeModelLibrary>(end);
    return o;
  }
};

inline flatbuffers::Offset<DatetimeModelLibrary> CreateDatetimeModelLibrary(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<libtextclassifier2::DatetimeModelLibrary_::Item>>> models = 0) {
  DatetimeModelLibraryBuilder builder_(_fbb);
  builder_.add_models(models);
  return builder_.Finish();
}

inline flatbuffers::Offset<DatetimeModelLibrary> CreateDatetimeModelLibraryDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<libtextclassifier2::DatetimeModelLibrary_::Item>> *models = nullptr) {
  return libtextclassifier2::CreateDatetimeModelLibrary(
      _fbb,
      models ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::DatetimeModelLibrary_::Item>>(*models) : 0);
}

flatbuffers::Offset<DatetimeModelLibrary> CreateDatetimeModelLibrary(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelLibraryT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

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

struct ModelTriggeringOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ModelTriggeringOptionsT NativeTableType;
  enum {
    VT_MIN_ANNOTATE_CONFIDENCE = 4,
    VT_ENABLED_MODES = 6
  };
  float min_annotate_confidence() const {
    return GetField<float>(VT_MIN_ANNOTATE_CONFIDENCE, 0.0f);
  }
  ModeFlag enabled_modes() const {
    return static_cast<ModeFlag>(GetField<int32_t>(VT_ENABLED_MODES, 7));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_MIN_ANNOTATE_CONFIDENCE) &&
           VerifyField<int32_t>(verifier, VT_ENABLED_MODES) &&
           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);
  }
  void add_enabled_modes(ModeFlag enabled_modes) {
    fbb_.AddElement<int32_t>(ModelTriggeringOptions::VT_ENABLED_MODES, static_cast<int32_t>(enabled_modes), 7);
  }
  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,
    ModeFlag enabled_modes = ModeFlag_ALL) {
  ModelTriggeringOptionsBuilder builder_(_fbb);
  builder_.add_enabled_modes(enabled_modes);
  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 OutputOptionsT : public flatbuffers::NativeTable {
  typedef OutputOptions TableType;
  std::vector<std::string> filtered_collections_annotation;
  std::vector<std::string> filtered_collections_classification;
  std::vector<std::string> filtered_collections_selection;
  OutputOptionsT() {
  }
};

struct OutputOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef OutputOptionsT NativeTableType;
  enum {
    VT_FILTERED_COLLECTIONS_ANNOTATION = 4,
    VT_FILTERED_COLLECTIONS_CLASSIFICATION = 6,
    VT_FILTERED_COLLECTIONS_SELECTION = 8
  };
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *filtered_collections_annotation() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_FILTERED_COLLECTIONS_ANNOTATION);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *filtered_collections_classification() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_FILTERED_COLLECTIONS_CLASSIFICATION);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *filtered_collections_selection() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_FILTERED_COLLECTIONS_SELECTION);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_FILTERED_COLLECTIONS_ANNOTATION) &&
           verifier.Verify(filtered_collections_annotation()) &&
           verifier.VerifyVectorOfStrings(filtered_collections_annotation()) &&
           VerifyOffset(verifier, VT_FILTERED_COLLECTIONS_CLASSIFICATION) &&
           verifier.Verify(filtered_collections_classification()) &&
           verifier.VerifyVectorOfStrings(filtered_collections_classification()) &&
           VerifyOffset(verifier, VT_FILTERED_COLLECTIONS_SELECTION) &&
           verifier.Verify(filtered_collections_selection()) &&
           verifier.VerifyVectorOfStrings(filtered_collections_selection()) &&
           verifier.EndTable();
  }
  OutputOptionsT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  void UnPackTo(OutputOptionsT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
  static flatbuffers::Offset<OutputOptions> Pack(flatbuffers::FlatBufferBuilder &_fbb, const OutputOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct OutputOptionsBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_filtered_collections_annotation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> filtered_collections_annotation) {
    fbb_.AddOffset(OutputOptions::VT_FILTERED_COLLECTIONS_ANNOTATION, filtered_collections_annotation);
  }
  void add_filtered_collections_classification(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> filtered_collections_classification) {
    fbb_.AddOffset(OutputOptions::VT_FILTERED_COLLECTIONS_CLASSIFICATION, filtered_collections_classification);
  }
  void add_filtered_collections_selection(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> filtered_collections_selection) {
    fbb_.AddOffset(OutputOptions::VT_FILTERED_COLLECTIONS_SELECTION, filtered_collections_selection);
  }
  explicit OutputOptionsBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  OutputOptionsBuilder &operator=(const OutputOptionsBuilder &);
  flatbuffers::Offset<OutputOptions> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<OutputOptions>(end);
    return o;
  }
};

inline flatbuffers::Offset<OutputOptions> CreateOutputOptions(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> filtered_collections_annotation = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> filtered_collections_classification = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> filtered_collections_selection = 0) {
  OutputOptionsBuilder builder_(_fbb);
  builder_.add_filtered_collections_selection(filtered_collections_selection);
  builder_.add_filtered_collections_classification(filtered_collections_classification);
  builder_.add_filtered_collections_annotation(filtered_collections_annotation);
  return builder_.Finish();
}

inline flatbuffers::Offset<OutputOptions> CreateOutputOptionsDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *filtered_collections_annotation = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *filtered_collections_classification = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *filtered_collections_selection = nullptr) {
  return libtextclassifier2::CreateOutputOptions(
      _fbb,
      filtered_collections_annotation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*filtered_collections_annotation) : 0,
      filtered_collections_classification ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*filtered_collections_classification) : 0,
      filtered_collections_selection ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*filtered_collections_selection) : 0);
}

flatbuffers::Offset<OutputOptions> CreateOutputOptions(flatbuffers::FlatBufferBuilder &_fbb, const OutputOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct ModelT : public flatbuffers::NativeTable {
  typedef Model TableType;
  std::string locales;
  int32_t version;
  std::string name;
  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<SelectionModelOptionsT> selection_options;
  std::unique_ptr<ClassificationModelOptionsT> classification_options;
  std::unique_ptr<RegexModelT> regex_model;
  std::unique_ptr<DatetimeModelT> datetime_model;
  std::unique_ptr<ModelTriggeringOptionsT> triggering_options;
  ModeFlag enabled_modes;
  bool snap_whitespace_selections;
  std::unique_ptr<OutputOptionsT> output_options;
  ModelT()
      : version(0),
        enabled_modes(ModeFlag_ALL),
        snap_whitespace_selections(true) {
  }
};

struct Model FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ModelT NativeTableType;
  enum {
    VT_LOCALES = 4,
    VT_VERSION = 6,
    VT_NAME = 8,
    VT_SELECTION_FEATURE_OPTIONS = 10,
    VT_CLASSIFICATION_FEATURE_OPTIONS = 12,
    VT_SELECTION_MODEL = 14,
    VT_CLASSIFICATION_MODEL = 16,
    VT_EMBEDDING_MODEL = 18,
    VT_SELECTION_OPTIONS = 20,
    VT_CLASSIFICATION_OPTIONS = 22,
    VT_REGEX_MODEL = 24,
    VT_DATETIME_MODEL = 26,
    VT_TRIGGERING_OPTIONS = 28,
    VT_ENABLED_MODES = 30,
    VT_SNAP_WHITESPACE_SELECTIONS = 32,
    VT_OUTPUT_OPTIONS = 34
  };
  const flatbuffers::String *locales() const {
    return GetPointer<const flatbuffers::String *>(VT_LOCALES);
  }
  int32_t version() const {
    return GetField<int32_t>(VT_VERSION, 0);
  }
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  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 SelectionModelOptions *selection_options() const {
    return GetPointer<const SelectionModelOptions *>(VT_SELECTION_OPTIONS);
  }
  const ClassificationModelOptions *classification_options() const {
    return GetPointer<const ClassificationModelOptions *>(VT_CLASSIFICATION_OPTIONS);
  }
  const RegexModel *regex_model() const {
    return GetPointer<const RegexModel *>(VT_REGEX_MODEL);
  }
  const DatetimeModel *datetime_model() const {
    return GetPointer<const DatetimeModel *>(VT_DATETIME_MODEL);
  }
  const ModelTriggeringOptions *triggering_options() const {
    return GetPointer<const ModelTriggeringOptions *>(VT_TRIGGERING_OPTIONS);
  }
  ModeFlag enabled_modes() const {
    return static_cast<ModeFlag>(GetField<int32_t>(VT_ENABLED_MODES, 7));
  }
  bool snap_whitespace_selections() const {
    return GetField<uint8_t>(VT_SNAP_WHITESPACE_SELECTIONS, 1) != 0;
  }
  const OutputOptions *output_options() const {
    return GetPointer<const OutputOptions *>(VT_OUTPUT_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_NAME) &&
           verifier.Verify(name()) &&
           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_SELECTION_OPTIONS) &&
           verifier.VerifyTable(selection_options()) &&
           VerifyOffset(verifier, VT_CLASSIFICATION_OPTIONS) &&
           verifier.VerifyTable(classification_options()) &&
           VerifyOffset(verifier, VT_REGEX_MODEL) &&
           verifier.VerifyTable(regex_model()) &&
           VerifyOffset(verifier, VT_DATETIME_MODEL) &&
           verifier.VerifyTable(datetime_model()) &&
           VerifyOffset(verifier, VT_TRIGGERING_OPTIONS) &&
           verifier.VerifyTable(triggering_options()) &&
           VerifyField<int32_t>(verifier, VT_ENABLED_MODES) &&
           VerifyField<uint8_t>(verifier, VT_SNAP_WHITESPACE_SELECTIONS) &&
           VerifyOffset(verifier, VT_OUTPUT_OPTIONS) &&
           verifier.VerifyTable(output_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_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(Model::VT_NAME, name);
  }
  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_selection_options(flatbuffers::Offset<SelectionModelOptions> selection_options) {
    fbb_.AddOffset(Model::VT_SELECTION_OPTIONS, selection_options);
  }
  void add_classification_options(flatbuffers::Offset<ClassificationModelOptions> classification_options) {
    fbb_.AddOffset(Model::VT_CLASSIFICATION_OPTIONS, classification_options);
  }
  void add_regex_model(flatbuffers::Offset<RegexModel> regex_model) {
    fbb_.AddOffset(Model::VT_REGEX_MODEL, regex_model);
  }
  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);
  }
  void add_enabled_modes(ModeFlag enabled_modes) {
    fbb_.AddElement<int32_t>(Model::VT_ENABLED_MODES, static_cast<int32_t>(enabled_modes), 7);
  }
  void add_snap_whitespace_selections(bool snap_whitespace_selections) {
    fbb_.AddElement<uint8_t>(Model::VT_SNAP_WHITESPACE_SELECTIONS, static_cast<uint8_t>(snap_whitespace_selections), 1);
  }
  void add_output_options(flatbuffers::Offset<OutputOptions> output_options) {
    fbb_.AddOffset(Model::VT_OUTPUT_OPTIONS, output_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<flatbuffers::String> name = 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<SelectionModelOptions> selection_options = 0,
    flatbuffers::Offset<ClassificationModelOptions> classification_options = 0,
    flatbuffers::Offset<RegexModel> regex_model = 0,
    flatbuffers::Offset<DatetimeModel> datetime_model = 0,
    flatbuffers::Offset<ModelTriggeringOptions> triggering_options = 0,
    ModeFlag enabled_modes = ModeFlag_ALL,
    bool snap_whitespace_selections = true,
    flatbuffers::Offset<OutputOptions> output_options = 0) {
  ModelBuilder builder_(_fbb);
  builder_.add_output_options(output_options);
  builder_.add_enabled_modes(enabled_modes);
  builder_.add_triggering_options(triggering_options);
  builder_.add_datetime_model(datetime_model);
  builder_.add_regex_model(regex_model);
  builder_.add_classification_options(classification_options);
  builder_.add_selection_options(selection_options);
  builder_.add_embedding_model(embedding_model);
  builder_.add_classification_model(classification_model);
  builder_.add_selection_model(selection_model);
  builder_.add_classification_feature_options(classification_feature_options);
  builder_.add_selection_feature_options(selection_feature_options);
  builder_.add_name(name);
  builder_.add_version(version);
  builder_.add_locales(locales);
  builder_.add_snap_whitespace_selections(snap_whitespace_selections);
  return builder_.Finish();
}

inline flatbuffers::Offset<Model> CreateModelDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *locales = nullptr,
    int32_t version = 0,
    const char *name = nullptr,
    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<SelectionModelOptions> selection_options = 0,
    flatbuffers::Offset<ClassificationModelOptions> classification_options = 0,
    flatbuffers::Offset<RegexModel> regex_model = 0,
    flatbuffers::Offset<DatetimeModel> datetime_model = 0,
    flatbuffers::Offset<ModelTriggeringOptions> triggering_options = 0,
    ModeFlag enabled_modes = ModeFlag_ALL,
    bool snap_whitespace_selections = true,
    flatbuffers::Offset<OutputOptions> output_options = 0) {
  return libtextclassifier2::CreateModel(
      _fbb,
      locales ? _fbb.CreateString(locales) : 0,
      version,
      name ? _fbb.CreateString(name) : 0,
      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,
      selection_options,
      classification_options,
      regex_model,
      datetime_model,
      triggering_options,
      enabled_modes,
      snap_whitespace_selections,
      output_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;
  bool score_single_token_spans_as_zero;
  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),
        score_single_token_spans_as_zero(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,
    VT_SCORE_SINGLE_TOKEN_SPANS_AS_ZERO = 18
  };
  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 score_single_token_spans_as_zero() const {
    return GetField<uint8_t>(VT_SCORE_SINGLE_TOKEN_SPANS_AS_ZERO, 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) &&
           VerifyField<uint8_t>(verifier, VT_SCORE_SINGLE_TOKEN_SPANS_AS_ZERO) &&
           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);
  }
  void add_score_single_token_spans_as_zero(bool score_single_token_spans_as_zero) {
    fbb_.AddElement<uint8_t>(BoundsSensitiveFeatures::VT_SCORE_SINGLE_TOKEN_SPANS_AS_ZERO, static_cast<uint8_t>(score_single_token_spans_as_zero), 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,
    bool score_single_token_spans_as_zero = 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_score_single_token_spans_as_zero(score_single_token_spans_as_zero);
  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 embedding_quantization_bits;
  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;
  FeatureProcessorOptionsT()
      : num_buckets(-1),
        embedding_size(-1),
        embedding_quantization_bits(8),
        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_INTERNAL_TOKENIZER),
        icu_preserve_whitespace_tokens(false),
        tokenize_on_script_change(false) {
  }
};

struct FeatureProcessorOptions FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FeatureProcessorOptionsT NativeTableType;
  enum {
    VT_NUM_BUCKETS = 4,
    VT_EMBEDDING_SIZE = 6,
    VT_EMBEDDING_QUANTIZATION_BITS = 8,
    VT_CONTEXT_SIZE = 10,
    VT_MAX_SELECTION_SPAN = 12,
    VT_CHARGRAM_ORDERS = 14,
    VT_MAX_WORD_LENGTH = 16,
    VT_UNICODE_AWARE_FEATURES = 18,
    VT_EXTRACT_CASE_FEATURE = 20,
    VT_EXTRACT_SELECTION_MASK_FEATURE = 22,
    VT_REGEXP_FEATURE = 24,
    VT_REMAP_DIGITS = 26,
    VT_LOWERCASE_TOKENS = 28,
    VT_SELECTION_REDUCED_OUTPUT_SPACE = 30,
    VT_COLLECTIONS = 32,
    VT_DEFAULT_COLLECTION = 34,
    VT_ONLY_USE_LINE_WITH_CLICK = 36,
    VT_SPLIT_TOKENS_ON_SELECTION_BOUNDARIES = 38,
    VT_TOKENIZATION_CODEPOINT_CONFIG = 40,
    VT_CENTER_TOKEN_SELECTION_METHOD = 42,
    VT_SNAP_LABEL_SPAN_BOUNDARIES_TO_CONTAINING_TOKENS = 44,
    VT_SUPPORTED_CODEPOINT_RANGES = 46,
    VT_INTERNAL_TOKENIZER_CODEPOINT_RANGES = 48,
    VT_MIN_SUPPORTED_CODEPOINT_RATIO = 50,
    VT_FEATURE_VERSION = 52,
    VT_TOKENIZATION_TYPE = 54,
    VT_ICU_PRESERVE_WHITESPACE_TOKENS = 56,
    VT_IGNORED_SPAN_BOUNDARY_CODEPOINTS = 58,
    VT_BOUNDS_SENSITIVE_FEATURES = 60,
    VT_ALLOWED_CHARGRAMS = 62,
    VT_TOKENIZE_ON_SCRIPT_CHANGE = 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 embedding_quantization_bits() const {
    return GetField<int32_t>(VT_EMBEDDING_QUANTIZATION_BITS, 8);
  }
  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, 1));
  }
  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;
  }
  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_EMBEDDING_QUANTIZATION_BITS) &&
           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) &&
           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_embedding_quantization_bits(int32_t embedding_quantization_bits) {
    fbb_.AddElement<int32_t>(FeatureProcessorOptions::VT_EMBEDDING_QUANTIZATION_BITS, embedding_quantization_bits, 8);
  }
  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), 1);
  }
  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);
  }
  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 embedding_quantization_bits = 8,
    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_INTERNAL_TOKENIZER,
    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) {
  FeatureProcessorOptionsBuilder builder_(_fbb);
  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_quantization_bits(embedding_quantization_bits);
  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 embedding_quantization_bits = 8,
    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_INTERNAL_TOKENIZER,
    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) {
  return libtextclassifier2::CreateFeatureProcessorOptions(
      _fbb,
      num_buckets,
      embedding_size,
      embedding_quantization_bits,
      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);
}

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

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

inline void CompressedBuffer::UnPackTo(CompressedBufferT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = buffer(); if (_e) { _o->buffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->buffer[_i] = _e->Get(_i); } } };
  { auto _e = uncompressed_size(); _o->uncompressed_size = _e; };
}

inline flatbuffers::Offset<CompressedBuffer> CompressedBuffer::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CompressedBufferT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateCompressedBuffer(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<CompressedBuffer> CreateCompressedBuffer(flatbuffers::FlatBufferBuilder &_fbb, const CompressedBufferT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CompressedBufferT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _buffer = _o->buffer.size() ? _fbb.CreateVector(_o->buffer) : 0;
  auto _uncompressed_size = _o->uncompressed_size;
  return libtextclassifier2::CreateCompressedBuffer(
      _fbb,
      _buffer,
      _uncompressed_size);
}

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

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; };
  { auto _e = address_min_num_tokens(); _o->address_min_num_tokens = _e; };
  { auto _e = max_num_tokens(); _o->max_num_tokens = _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;
  auto _address_min_num_tokens = _o->address_min_num_tokens;
  auto _max_num_tokens = _o->max_num_tokens;
  return libtextclassifier2::CreateClassificationModelOptions(
      _fbb,
      _phone_min_num_digits,
      _phone_max_num_digits,
      _address_min_num_tokens,
      _max_num_tokens);
}

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_modes(); _o->enabled_modes = _e; };
  { auto _e = target_classification_score(); _o->target_classification_score = _e; };
  { auto _e = priority_score(); _o->priority_score = _e; };
  { auto _e = use_approximate_matching(); _o->use_approximate_matching = _e; };
  { auto _e = compressed_pattern(); if (_e) _o->compressed_pattern = std::unique_ptr<libtextclassifier2::CompressedBufferT>(_e->UnPack(_resolver)); };
}

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_modes = _o->enabled_modes;
  auto _target_classification_score = _o->target_classification_score;
  auto _priority_score = _o->priority_score;
  auto _use_approximate_matching = _o->use_approximate_matching;
  auto _compressed_pattern = _o->compressed_pattern ? CreateCompressedBuffer(_fbb, _o->compressed_pattern.get(), _rehasher) : 0;
  return libtextclassifier2::RegexModel_::CreatePattern(
      _fbb,
      _collection_name,
      _pattern,
      _enabled_modes,
      _target_classification_score,
      _priority_score,
      _use_approximate_matching,
      _compressed_pattern);
}

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

namespace DatetimeModelPattern_ {

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

inline void Regex::UnPackTo(RegexT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = pattern(); if (_e) _o->pattern = _e->str(); };
  { auto _e = groups(); if (_e) { _o->groups.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->groups[_i] = (DatetimeGroupType)_e->Get(_i); } } };
  { auto _e = compressed_pattern(); if (_e) _o->compressed_pattern = std::unique_ptr<libtextclassifier2::CompressedBufferT>(_e->UnPack(_resolver)); };
}

inline flatbuffers::Offset<Regex> Regex::Pack(flatbuffers::FlatBufferBuilder &_fbb, const RegexT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateRegex(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<Regex> CreateRegex(flatbuffers::FlatBufferBuilder &_fbb, const RegexT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const RegexT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _pattern = _o->pattern.empty() ? 0 : _fbb.CreateString(_o->pattern);
  auto _groups = _o->groups.size() ? _fbb.CreateVector((const int32_t*)_o->groups.data(), _o->groups.size()) : 0;
  auto _compressed_pattern = _o->compressed_pattern ? CreateCompressedBuffer(_fbb, _o->compressed_pattern.get(), _rehasher) : 0;
  return libtextclassifier2::DatetimeModelPattern_::CreateRegex(
      _fbb,
      _pattern,
      _groups,
      _compressed_pattern);
}

}  // namespace DatetimeModelPattern_

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] = std::unique_ptr<libtextclassifier2::DatetimeModelPattern_::RegexT>(_e->Get(_i)->UnPack(_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); } } };
  { auto _e = target_classification_score(); _o->target_classification_score = _e; };
  { auto _e = priority_score(); _o->priority_score = _e; };
  { auto _e = enabled_modes(); _o->enabled_modes = _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.CreateVector<flatbuffers::Offset<libtextclassifier2::DatetimeModelPattern_::Regex>> (_o->regexes.size(), [](size_t i, _VectorArgs *__va) { return CreateRegex(*__va->__fbb, __va->__o->regexes[i].get(), __va->__rehasher); }, &_va ) : 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;
  auto _enabled_modes = _o->enabled_modes;
  return libtextclassifier2::CreateDatetimeModelPattern(
      _fbb,
      _regexes,
      _locales,
      _target_classification_score,
      _priority_score,
      _enabled_modes);
}

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); } } };
  { auto _e = compressed_pattern(); if (_e) _o->compressed_pattern = std::unique_ptr<CompressedBufferT>(_e->UnPack(_resolver)); };
}

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;
  auto _compressed_pattern = _o->compressed_pattern ? CreateCompressedBuffer(_fbb, _o->compressed_pattern.get(), _rehasher) : 0;
  return libtextclassifier2::CreateDatetimeModelExtractor(
      _fbb,
      _extractor,
      _pattern,
      _locales,
      _compressed_pattern);
}

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)); } } };
  { auto _e = use_extractors_for_locating(); _o->use_extractors_for_locating = _e; };
  { auto _e = default_locales(); if (_e) { _o->default_locales.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->default_locales[_i] = _e->Get(_i); } } };
}

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;
  auto _use_extractors_for_locating = _o->use_extractors_for_locating;
  auto _default_locales = _o->default_locales.size() ? _fbb.CreateVector(_o->default_locales) : 0;
  return libtextclassifier2::CreateDatetimeModel(
      _fbb,
      _locales,
      _patterns,
      _extractors,
      _use_extractors_for_locating,
      _default_locales);
}

namespace DatetimeModelLibrary_ {

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

inline void Item::UnPackTo(ItemT *_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 = std::unique_ptr<libtextclassifier2::DatetimeModelT>(_e->UnPack(_resolver)); };
}

inline flatbuffers::Offset<Item> Item::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ItemT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateItem(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<Item> CreateItem(flatbuffers::FlatBufferBuilder &_fbb, const ItemT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ItemT* __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 ? CreateDatetimeModel(_fbb, _o->value.get(), _rehasher) : 0;
  return libtextclassifier2::DatetimeModelLibrary_::CreateItem(
      _fbb,
      _key,
      _value);
}

}  // namespace DatetimeModelLibrary_

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

inline void DatetimeModelLibrary::UnPackTo(DatetimeModelLibraryT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = models(); if (_e) { _o->models.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->models[_i] = std::unique_ptr<libtextclassifier2::DatetimeModelLibrary_::ItemT>(_e->Get(_i)->UnPack(_resolver)); } } };
}

inline flatbuffers::Offset<DatetimeModelLibrary> DatetimeModelLibrary::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelLibraryT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateDatetimeModelLibrary(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<DatetimeModelLibrary> CreateDatetimeModelLibrary(flatbuffers::FlatBufferBuilder &_fbb, const DatetimeModelLibraryT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DatetimeModelLibraryT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _models = _o->models.size() ? _fbb.CreateVector<flatbuffers::Offset<libtextclassifier2::DatetimeModelLibrary_::Item>> (_o->models.size(), [](size_t i, _VectorArgs *__va) { return CreateItem(*__va->__fbb, __va->__o->models[i].get(), __va->__rehasher); }, &_va ) : 0;
  return libtextclassifier2::CreateDatetimeModelLibrary(
      _fbb,
      _models);
}

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; };
  { auto _e = enabled_modes(); _o->enabled_modes = _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;
  auto _enabled_modes = _o->enabled_modes;
  return libtextclassifier2::CreateModelTriggeringOptions(
      _fbb,
      _min_annotate_confidence,
      _enabled_modes);
}

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

inline void OutputOptions::UnPackTo(OutputOptionsT *_o, const flatbuffers::resolver_function_t *_resolver) const {
  (void)_o;
  (void)_resolver;
  { auto _e = filtered_collections_annotation(); if (_e) { _o->filtered_collections_annotation.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->filtered_collections_annotation[_i] = _e->Get(_i)->str(); } } };
  { auto _e = filtered_collections_classification(); if (_e) { _o->filtered_collections_classification.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->filtered_collections_classification[_i] = _e->Get(_i)->str(); } } };
  { auto _e = filtered_collections_selection(); if (_e) { _o->filtered_collections_selection.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->filtered_collections_selection[_i] = _e->Get(_i)->str(); } } };
}

inline flatbuffers::Offset<OutputOptions> OutputOptions::Pack(flatbuffers::FlatBufferBuilder &_fbb, const OutputOptionsT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
  return CreateOutputOptions(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<OutputOptions> CreateOutputOptions(flatbuffers::FlatBufferBuilder &_fbb, const OutputOptionsT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
  (void)_rehasher;
  (void)_o;
  struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const OutputOptionsT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
  auto _filtered_collections_annotation = _o->filtered_collections_annotation.size() ? _fbb.CreateVectorOfStrings(_o->filtered_collections_annotation) : 0;
  auto _filtered_collections_classification = _o->filtered_collections_classification.size() ? _fbb.CreateVectorOfStrings(_o->filtered_collections_classification) : 0;
  auto _filtered_collections_selection = _o->filtered_collections_selection.size() ? _fbb.CreateVectorOfStrings(_o->filtered_collections_selection) : 0;
  return libtextclassifier2::CreateOutputOptions(
      _fbb,
      _filtered_collections_annotation,
      _filtered_collections_classification,
      _filtered_collections_selection);
}

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 = name(); if (_e) _o->name = _e->str(); };
  { 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 = selection_options(); if (_e) _o->selection_options = std::unique_ptr<SelectionModelOptionsT>(_e->UnPack(_resolver)); };
  { auto _e = classification_options(); if (_e) _o->classification_options = std::unique_ptr<ClassificationModelOptionsT>(_e->UnPack(_resolver)); };
  { auto _e = regex_model(); if (_e) _o->regex_model = std::unique_ptr<RegexModelT>(_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)); };
  { auto _e = enabled_modes(); _o->enabled_modes = _e; };
  { auto _e = snap_whitespace_selections(); _o->snap_whitespace_selections = _e; };
  { auto _e = output_options(); if (_e) _o->output_options = std::unique_ptr<OutputOptionsT>(_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 _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
  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 _selection_options = _o->selection_options ? CreateSelectionModelOptions(_fbb, _o->selection_options.get(), _rehasher) : 0;
  auto _classification_options = _o->classification_options ? CreateClassificationModelOptions(_fbb, _o->classification_options.get(), _rehasher) : 0;
  auto _regex_model = _o->regex_model ? CreateRegexModel(_fbb, _o->regex_model.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;
  auto _enabled_modes = _o->enabled_modes;
  auto _snap_whitespace_selections = _o->snap_whitespace_selections;
  auto _output_options = _o->output_options ? CreateOutputOptions(_fbb, _o->output_options.get(), _rehasher) : 0;
  return libtextclassifier2::CreateModel(
      _fbb,
      _locales,
      _version,
      _name,
      _selection_feature_options,
      _classification_feature_options,
      _selection_model,
      _classification_model,
      _embedding_model,
      _selection_options,
      _classification_options,
      _regex_model,
      _datetime_model,
      _triggering_options,
      _enabled_modes,
      _snap_whitespace_selections,
      _output_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; };
  { auto _e = score_single_token_spans_as_zero(); _o->score_single_token_spans_as_zero = _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;
  auto _score_single_token_spans_as_zero = _o->score_single_token_spans_as_zero;
  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,
      _score_single_token_spans_as_zero);
}

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 = embedding_quantization_bits(); _o->embedding_quantization_bits = _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; };
}

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 _embedding_quantization_bits = _o->embedding_quantization_bits;
  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;
  return libtextclassifier2::CreateFeatureProcessorOptions(
      _fbb,
      _num_buckets,
      _embedding_size,
      _embedding_quantization_bits,
      _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);
}

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_
