// Generated from jackson-core which is licensed under the Apache License 2.0.
// The following copyright from the original authors applies.
// See https://github.com/FasterXML/jackson-core/blob/2.14/LICENSE
//
// Copyright (c) 2007 - The Jackson Project Authors
// 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.

// Autogenerated by jnigen. DO NOT EDIT!

// ignore_for_file: annotate_overrides
// ignore_for_file: camel_case_extensions
// ignore_for_file: camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: doc_directive_unknown
// ignore_for_file: file_names
// ignore_for_file: lines_longer_than_80_chars
// ignore_for_file: no_leading_underscores_for_local_identifiers
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: overridden_fields
// ignore_for_file: unnecessary_cast
// ignore_for_file: unused_element
// ignore_for_file: unused_field
// ignore_for_file: unused_import
// ignore_for_file: unused_local_variable
// ignore_for_file: unused_shown_name
// ignore_for_file: use_super_parameters

import "dart:isolate" show ReceivePort;
import "dart:ffi" as ffi;
import "package:jni/internal_helpers_for_jnigen.dart";
import "package:jni/jni.dart" as jni;

import "JsonParser.dart" as jsonparser_;

/// from: com.fasterxml.jackson.core.JsonFactory$Feature
///
/// Enumeration that defines all on/off features that can only be
/// changed for JsonFactory.
class JsonFactory_Feature extends jni.JObject {
  @override
  late final jni.JObjType<JsonFactory_Feature> $type = type;

  JsonFactory_Feature.fromReference(
    jni.JReference reference,
  ) : super.fromReference(reference);

  static final _class =
      jni.JClass.forName(r"com/fasterxml/jackson/core/JsonFactory$Feature");

  /// The type which includes information such as the signature of this class.
  static const type = $JsonFactory_FeatureType();
  static final _id_values = _class.staticMethodId(
    r"values",
    r"()[Lcom/fasterxml/jackson/core/JsonFactory$Feature;",
  );

  /// from: static public com.fasterxml.jackson.core.JsonFactory.Feature[] values()
  /// The returned object must be released after use, by calling the [release] method.
  static jni.JArray<JsonFactory_Feature> values() {
    return _id_values(
        _class, const jni.JArrayType($JsonFactory_FeatureType()), []);
  }

  static final _id_valueOf = _class.staticMethodId(
    r"valueOf",
    r"(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonFactory$Feature;",
  );

  /// from: static public com.fasterxml.jackson.core.JsonFactory.Feature valueOf(java.lang.String name)
  /// The returned object must be released after use, by calling the [release] method.
  static JsonFactory_Feature valueOf(
    jni.JString name,
  ) {
    return _id_valueOf(
        _class, const $JsonFactory_FeatureType(), [name.reference.pointer]);
  }

  static final _id_collectDefaults = _class.staticMethodId(
    r"collectDefaults",
    r"()I",
  );

  /// from: static public int collectDefaults()
  ///
  /// Method that calculates bit set (flags) of all features that
  /// are enabled by default.
  ///@return Bit field of features enabled by default
  static int collectDefaults() {
    return _id_collectDefaults(_class, const jni.jintType(), []);
  }

  static final _id_enabledByDefault = _class.instanceMethodId(
    r"enabledByDefault",
    r"()Z",
  );

  /// from: public boolean enabledByDefault()
  bool enabledByDefault() {
    return _id_enabledByDefault(this, const jni.jbooleanType(), []);
  }

  static final _id_enabledIn = _class.instanceMethodId(
    r"enabledIn",
    r"(I)Z",
  );

  /// from: public boolean enabledIn(int flags)
  bool enabledIn(
    int flags,
  ) {
    return _id_enabledIn(
        this, const jni.jbooleanType(), [jni.JValueInt(flags)]);
  }

  static final _id_getMask = _class.instanceMethodId(
    r"getMask",
    r"()I",
  );

  /// from: public int getMask()
  int getMask() {
    return _id_getMask(this, const jni.jintType(), []);
  }
}

final class $JsonFactory_FeatureType extends jni.JObjType<JsonFactory_Feature> {
  const $JsonFactory_FeatureType();

  @override
  String get signature => r"Lcom/fasterxml/jackson/core/JsonFactory$Feature;";

  @override
  JsonFactory_Feature fromReference(jni.JReference reference) =>
      JsonFactory_Feature.fromReference(reference);

  @override
  jni.JObjType get superType => const jni.JObjectType();

  @override
  final superCount = 1;

  @override
  int get hashCode => ($JsonFactory_FeatureType).hashCode;

  @override
  bool operator ==(Object other) {
    return other.runtimeType == ($JsonFactory_FeatureType) &&
        other is $JsonFactory_FeatureType;
  }
}

/// from: com.fasterxml.jackson.core.JsonFactory
///
/// The main factory class of Jackson package, used to configure and
/// construct reader (aka parser, JsonParser)
/// and writer (aka generator, JsonGenerator)
/// instances.
///
/// Factory instances are thread-safe and reusable after configuration
/// (if any). Typically applications and services use only a single
/// globally shared factory instance, unless they need differently
/// configured factories. Factory reuse is important if efficiency matters;
/// most recycling of expensive construct is done on per-factory basis.
///
/// Creation of a factory instance is a light-weight operation,
/// and since there is no need for pluggable alternative implementations
/// (as there is no "standard" JSON processor API to implement),
/// the default constructor is used for constructing factory
/// instances.
///@author Tatu Saloranta
class JsonFactory extends jni.JObject {
  @override
  late final jni.JObjType<JsonFactory> $type = type;

  JsonFactory.fromReference(
    jni.JReference reference,
  ) : super.fromReference(reference);

  static final _class =
      jni.JClass.forName(r"com/fasterxml/jackson/core/JsonFactory");

  /// The type which includes information such as the signature of this class.
  static const type = $JsonFactoryType();
  static final _id_FORMAT_NAME_JSON = _class.staticFieldId(
    r"FORMAT_NAME_JSON",
    r"Ljava/lang/String;",
  );

  /// from: static public final java.lang.String FORMAT_NAME_JSON
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Name used to identify JSON format
  /// (and returned by \#getFormatName()
  static jni.JString get FORMAT_NAME_JSON =>
      _id_FORMAT_NAME_JSON.get(_class, const jni.JStringType());

  static final _id_DEFAULT_FACTORY_FEATURE_FLAGS = _class.staticFieldId(
    r"DEFAULT_FACTORY_FEATURE_FLAGS",
    r"I",
  );

  /// from: static protected final int DEFAULT_FACTORY_FEATURE_FLAGS
  ///
  /// Bitfield (set of flags) of all factory features that are enabled by default.
  static int get DEFAULT_FACTORY_FEATURE_FLAGS =>
      _id_DEFAULT_FACTORY_FEATURE_FLAGS.get(_class, const jni.jintType());

  static final _id_DEFAULT_PARSER_FEATURE_FLAGS = _class.staticFieldId(
    r"DEFAULT_PARSER_FEATURE_FLAGS",
    r"I",
  );

  /// from: static protected final int DEFAULT_PARSER_FEATURE_FLAGS
  ///
  /// Bitfield (set of flags) of all parser features that are enabled
  /// by default.
  static int get DEFAULT_PARSER_FEATURE_FLAGS =>
      _id_DEFAULT_PARSER_FEATURE_FLAGS.get(_class, const jni.jintType());

  static final _id_DEFAULT_GENERATOR_FEATURE_FLAGS = _class.staticFieldId(
    r"DEFAULT_GENERATOR_FEATURE_FLAGS",
    r"I",
  );

  /// from: static protected final int DEFAULT_GENERATOR_FEATURE_FLAGS
  ///
  /// Bitfield (set of flags) of all generator features that are enabled
  /// by default.
  static int get DEFAULT_GENERATOR_FEATURE_FLAGS =>
      _id_DEFAULT_GENERATOR_FEATURE_FLAGS.get(_class, const jni.jintType());

  static final _id_DEFAULT_ROOT_VALUE_SEPARATOR = _class.staticFieldId(
    r"DEFAULT_ROOT_VALUE_SEPARATOR",
    r"Lcom/fasterxml/jackson/core/SerializableString;",
  );

  /// from: static public final com.fasterxml.jackson.core.SerializableString DEFAULT_ROOT_VALUE_SEPARATOR
  /// The returned object must be released after use, by calling the [release] method.
  static jni.JObject get DEFAULT_ROOT_VALUE_SEPARATOR =>
      _id_DEFAULT_ROOT_VALUE_SEPARATOR.get(_class, const jni.JObjectType());

  static final _id_new0 = _class.constructorId(
    r"()V",
  );

  /// from: public void <init>()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Default constructor used to create factory instances.
  /// Creation of a factory instance is a light-weight operation,
  /// but it is still a good idea to reuse limited number of
  /// factory instances (and quite often just a single instance):
  /// factories are used as context for storing some reused
  /// processing objects (such as symbol tables parsers use)
  /// and this reuse only works within context of a single
  /// factory instance.
  factory JsonFactory() {
    return JsonFactory.fromReference(_id_new0(_class, referenceType, []));
  }

  static final _id_new1 = _class.constructorId(
    r"(Lcom/fasterxml/jackson/core/ObjectCodec;)V",
  );

  /// from: public void <init>(com.fasterxml.jackson.core.ObjectCodec oc)
  /// The returned object must be released after use, by calling the [release] method.
  factory JsonFactory.new1(
    jni.JObject oc,
  ) {
    return JsonFactory.fromReference(
        _id_new1(_class, referenceType, [oc.reference.pointer]));
  }

  static final _id_new2 = _class.constructorId(
    r"(Lcom/fasterxml/jackson/core/JsonFactory;Lcom/fasterxml/jackson/core/ObjectCodec;)V",
  );

  /// from: protected void <init>(com.fasterxml.jackson.core.JsonFactory src, com.fasterxml.jackson.core.ObjectCodec codec)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Constructor used when copy()ing a factory instance.
  ///@param src Original factory to copy settings from
  ///@param codec Databinding-level codec to use, if any
  ///@since 2.2.1
  factory JsonFactory.new2(
    JsonFactory src,
    jni.JObject codec,
  ) {
    return JsonFactory.fromReference(_id_new2(_class, referenceType,
        [src.reference.pointer, codec.reference.pointer]));
  }

  static final _id_new3 = _class.constructorId(
    r"(Lcom/fasterxml/jackson/core/JsonFactoryBuilder;)V",
  );

  /// from: public void <init>(com.fasterxml.jackson.core.JsonFactoryBuilder b)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Constructor used by JsonFactoryBuilder for instantiation.
  ///@param b Builder that contains settings to use
  ///@since 2.10
  factory JsonFactory.new3(
    jni.JObject b,
  ) {
    return JsonFactory.fromReference(
        _id_new3(_class, referenceType, [b.reference.pointer]));
  }

  static final _id_new4 = _class.constructorId(
    r"(Lcom/fasterxml/jackson/core/TSFBuilder;Z)V",
  );

  /// from: protected void <init>(com.fasterxml.jackson.core.TSFBuilder<?,?> b, boolean bogus)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Constructor for subtypes; needed to work around the fact that before 3.0,
  /// this factory has cumbersome dual role as generic type as well as actual
  /// implementation for json.
  ///@param b Builder that contains settings to use
  ///@param bogus Argument only needed to separate constructor signature; ignored
  factory JsonFactory.new4(
    jni.JObject b,
    bool bogus,
  ) {
    return JsonFactory.fromReference(
        _id_new4(_class, referenceType, [b.reference.pointer, bogus ? 1 : 0]));
  }

  static final _id_rebuild = _class.instanceMethodId(
    r"rebuild",
    r"()Lcom/fasterxml/jackson/core/TSFBuilder;",
  );

  /// from: public com.fasterxml.jackson.core.TSFBuilder<?,?> rebuild()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method that allows construction of differently configured factory, starting
  /// with settings of this factory.
  ///@return Builder instance to use
  ///@since 2.10
  jni.JObject rebuild() {
    return _id_rebuild(this, const jni.JObjectType(), []);
  }

  static final _id_builder = _class.staticMethodId(
    r"builder",
    r"()Lcom/fasterxml/jackson/core/TSFBuilder;",
  );

  /// from: static public com.fasterxml.jackson.core.TSFBuilder<?,?> builder()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Main factory method to use for constructing JsonFactory instances with
  /// different configuration: creates and returns a builder for collecting configuration
  /// settings; instance created by calling {@code build()} after all configuration
  /// set.
  ///
  /// NOTE: signature unfortunately does not expose true implementation type; this
  /// will be fixed in 3.0.
  ///@return Builder instance to use
  static jni.JObject builder() {
    return _id_builder(_class, const jni.JObjectType(), []);
  }

  static final _id_copy = _class.instanceMethodId(
    r"copy",
    r"()Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory copy()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing a new JsonFactory that has
  /// the same settings as this instance, but is otherwise
  /// independent (i.e. nothing is actually shared, symbol tables
  /// are separate).
  /// Note that ObjectCodec reference is not copied but is
  /// set to null; caller typically needs to set it after calling
  /// this method. Reason for this is that the codec is used for
  /// callbacks, and assumption is that there is strict 1-to-1
  /// mapping between codec, factory. Caller has to, then, explicitly
  /// set codec after making the copy.
  ///@return Copy of this factory instance
  ///@since 2.1
  JsonFactory copy() {
    return _id_copy(this, const $JsonFactoryType(), []);
  }

  static final _id_readResolve = _class.instanceMethodId(
    r"readResolve",
    r"()Ljava/lang/Object;",
  );

  /// from: protected java.lang.Object readResolve()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method that we need to override to actually make restoration go
  /// through constructors etc: needed to allow JDK serializability of
  /// factory instances.
  ///
  /// Note: must be overridden by sub-classes as well.
  ///@return Newly constructed instance
  jni.JObject readResolve() {
    return _id_readResolve(this, const jni.JObjectType(), []);
  }

  static final _id_requiresPropertyOrdering = _class.instanceMethodId(
    r"requiresPropertyOrdering",
    r"()Z",
  );

  /// from: public boolean requiresPropertyOrdering()
  ///
  /// Introspection method that higher-level functionality may call
  /// to see whether underlying data format requires a stable ordering
  /// of object properties or not.
  /// This is usually used for determining
  /// whether to force a stable ordering (like alphabetic ordering by name)
  /// if no ordering if explicitly specified.
  ///
  /// Default implementation returns <code>false</code> as JSON does NOT
  /// require stable ordering. Formats that require ordering include positional
  /// textual formats like <code>CSV</code>, and schema-based binary formats
  /// like <code>Avro</code>.
  ///@return Whether format supported by this factory
  ///   requires Object properties to be ordered.
  ///@since 2.3
  bool requiresPropertyOrdering() {
    return _id_requiresPropertyOrdering(this, const jni.jbooleanType(), []);
  }

  static final _id_canHandleBinaryNatively = _class.instanceMethodId(
    r"canHandleBinaryNatively",
    r"()Z",
  );

  /// from: public boolean canHandleBinaryNatively()
  ///
  /// Introspection method that higher-level functionality may call
  /// to see whether underlying data format can read and write binary
  /// data natively; that is, embeded it as-is without using encodings
  /// such as Base64.
  ///
  /// Default implementation returns <code>false</code> as JSON does not
  /// support native access: all binary content must use Base64 encoding.
  /// Most binary formats (like Smile and Avro) support native binary content.
  ///@return Whether format supported by this factory
  ///    supports native binary content
  ///@since 2.3
  bool canHandleBinaryNatively() {
    return _id_canHandleBinaryNatively(this, const jni.jbooleanType(), []);
  }

  static final _id_canUseCharArrays = _class.instanceMethodId(
    r"canUseCharArrays",
    r"()Z",
  );

  /// from: public boolean canUseCharArrays()
  ///
  /// Introspection method that can be used by base factory to check
  /// whether access using <code>char[]</code> is something that actual
  /// parser implementations can take advantage of, over having to
  /// use java.io.Reader. Sub-types are expected to override
  /// definition; default implementation (suitable for JSON) alleges
  /// that optimization are possible; and thereby is likely to try
  /// to access java.lang.String content by first copying it into
  /// recyclable intermediate buffer.
  ///@return Whether access to decoded textual content can be efficiently
  ///   accessed using parser method {@code getTextCharacters()}.
  ///@since 2.4
  bool canUseCharArrays() {
    return _id_canUseCharArrays(this, const jni.jbooleanType(), []);
  }

  static final _id_canParseAsync = _class.instanceMethodId(
    r"canParseAsync",
    r"()Z",
  );

  /// from: public boolean canParseAsync()
  ///
  /// Introspection method that can be used to check whether this
  /// factory can create non-blocking parsers: parsers that do not
  /// use blocking I/O abstractions but instead use a
  /// com.fasterxml.jackson.core.async.NonBlockingInputFeeder.
  ///@return Whether this factory supports non-blocking ("async") parsing or
  ///    not (and consequently whether {@code createNonBlockingXxx()} method(s) work)
  ///@since 2.9
  bool canParseAsync() {
    return _id_canParseAsync(this, const jni.jbooleanType(), []);
  }

  static final _id_getFormatReadFeatureType = _class.instanceMethodId(
    r"getFormatReadFeatureType",
    r"()Ljava/lang/Class;",
  );

  /// from: public java.lang.Class<? extends com.fasterxml.jackson.core.FormatFeature> getFormatReadFeatureType()
  /// The returned object must be released after use, by calling the [release] method.
  jni.JObject getFormatReadFeatureType() {
    return _id_getFormatReadFeatureType(this, const jni.JObjectType(), []);
  }

  static final _id_getFormatWriteFeatureType = _class.instanceMethodId(
    r"getFormatWriteFeatureType",
    r"()Ljava/lang/Class;",
  );

  /// from: public java.lang.Class<? extends com.fasterxml.jackson.core.FormatFeature> getFormatWriteFeatureType()
  /// The returned object must be released after use, by calling the [release] method.
  jni.JObject getFormatWriteFeatureType() {
    return _id_getFormatWriteFeatureType(this, const jni.JObjectType(), []);
  }

  static final _id_canUseSchema = _class.instanceMethodId(
    r"canUseSchema",
    r"(Lcom/fasterxml/jackson/core/FormatSchema;)Z",
  );

  /// from: public boolean canUseSchema(com.fasterxml.jackson.core.FormatSchema schema)
  ///
  /// Method that can be used to quickly check whether given schema
  /// is something that parsers and/or generators constructed by this
  /// factory could use. Note that this means possible use, at the level
  /// of data format (i.e. schema is for same data format as parsers and
  /// generators this factory constructs); individual schema instances
  /// may have further usage restrictions.
  ///@param schema Schema instance to check
  ///@return Whether parsers and generators constructed by this factory
  ///   can use specified format schema instance
  bool canUseSchema(
    jni.JObject schema,
  ) {
    return _id_canUseSchema(
        this, const jni.jbooleanType(), [schema.reference.pointer]);
  }

  static final _id_getFormatName = _class.instanceMethodId(
    r"getFormatName",
    r"()Ljava/lang/String;",
  );

  /// from: public java.lang.String getFormatName()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method that returns short textual id identifying format
  /// this factory supports.
  ///
  /// Note: sub-classes should override this method; default
  /// implementation will return null for all sub-classes
  ///@return Name of the format handled by parsers, generators this factory creates
  jni.JString getFormatName() {
    return _id_getFormatName(this, const jni.JStringType(), []);
  }

  static final _id_hasFormat = _class.instanceMethodId(
    r"hasFormat",
    r"(Lcom/fasterxml/jackson/core/format/InputAccessor;)Lcom/fasterxml/jackson/core/format/MatchStrength;",
  );

  /// from: public com.fasterxml.jackson.core.format.MatchStrength hasFormat(com.fasterxml.jackson.core.format.InputAccessor acc)
  /// The returned object must be released after use, by calling the [release] method.
  jni.JObject hasFormat(
    jni.JObject acc,
  ) {
    return _id_hasFormat(
        this, const jni.JObjectType(), [acc.reference.pointer]);
  }

  static final _id_requiresCustomCodec = _class.instanceMethodId(
    r"requiresCustomCodec",
    r"()Z",
  );

  /// from: public boolean requiresCustomCodec()
  ///
  /// Method that can be called to determine if a custom
  /// ObjectCodec is needed for binding data parsed
  /// using JsonParser constructed by this factory
  /// (which typically also implies the same for serialization
  /// with JsonGenerator).
  ///@return True if custom codec is needed with parsers and
  ///   generators created by this factory; false if a general
  ///   ObjectCodec is enough
  ///@since 2.1
  bool requiresCustomCodec() {
    return _id_requiresCustomCodec(this, const jni.jbooleanType(), []);
  }

  static final _id_hasJSONFormat = _class.instanceMethodId(
    r"hasJSONFormat",
    r"(Lcom/fasterxml/jackson/core/format/InputAccessor;)Lcom/fasterxml/jackson/core/format/MatchStrength;",
  );

  /// from: protected com.fasterxml.jackson.core.format.MatchStrength hasJSONFormat(com.fasterxml.jackson.core.format.InputAccessor acc)
  /// The returned object must be released after use, by calling the [release] method.
  jni.JObject hasJSONFormat(
    jni.JObject acc,
  ) {
    return _id_hasJSONFormat(
        this, const jni.JObjectType(), [acc.reference.pointer]);
  }

  static final _id_version = _class.instanceMethodId(
    r"version",
    r"()Lcom/fasterxml/jackson/core/Version;",
  );

  /// from: public com.fasterxml.jackson.core.Version version()
  /// The returned object must be released after use, by calling the [release] method.
  jni.JObject version() {
    return _id_version(this, const jni.JObjectType(), []);
  }

  static final _id_configure = _class.instanceMethodId(
    r"configure",
    r"(Lcom/fasterxml/jackson/core/JsonFactory$Feature;Z)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public final com.fasterxml.jackson.core.JsonFactory configure(com.fasterxml.jackson.core.JsonFactory.Feature f, boolean state)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for enabling or disabling specified parser feature
  /// (check JsonParser.Feature for list of features)
  ///@param f Feature to enable/disable
  ///@param state Whether to enable or disable the feature
  ///@return This factory instance (to allow call chaining)
  ///@deprecated since 2.10 use JsonFactoryBuilder\#configure(JsonFactory.Feature, boolean) instead
  JsonFactory configure(
    JsonFactory_Feature f,
    bool state,
  ) {
    return _id_configure(
        this, const $JsonFactoryType(), [f.reference.pointer, state ? 1 : 0]);
  }

  static final _id_enable = _class.instanceMethodId(
    r"enable",
    r"(Lcom/fasterxml/jackson/core/JsonFactory$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory enable(com.fasterxml.jackson.core.JsonFactory.Feature f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for enabling specified parser feature
  /// (check JsonFactory.Feature for list of features)
  ///@param f Feature to enable
  ///@return This factory instance (to allow call chaining)
  ///@deprecated since 2.10 use JsonFactoryBuilder\#configure(JsonFactory.Feature, boolean) instead
  JsonFactory enable(
    JsonFactory_Feature f,
  ) {
    return _id_enable(this, const $JsonFactoryType(), [f.reference.pointer]);
  }

  static final _id_disable = _class.instanceMethodId(
    r"disable",
    r"(Lcom/fasterxml/jackson/core/JsonFactory$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory disable(com.fasterxml.jackson.core.JsonFactory.Feature f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for disabling specified parser features
  /// (check JsonFactory.Feature for list of features)
  ///@param f Feature to disable
  ///@return This factory instance (to allow call chaining)
  ///@deprecated since 2.10 use JsonFactoryBuilder\#configure(JsonFactory.Feature, boolean) instead
  JsonFactory disable(
    JsonFactory_Feature f,
  ) {
    return _id_disable(this, const $JsonFactoryType(), [f.reference.pointer]);
  }

  static final _id_isEnabled = _class.instanceMethodId(
    r"isEnabled",
    r"(Lcom/fasterxml/jackson/core/JsonFactory$Feature;)Z",
  );

  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.JsonFactory.Feature f)
  ///
  /// Checked whether specified parser feature is enabled.
  ///@param f Feature to check
  ///@return True if the specified feature is enabled
  bool isEnabled(
    JsonFactory_Feature f,
  ) {
    return _id_isEnabled(this, const jni.jbooleanType(), [f.reference.pointer]);
  }

  static final _id_getParserFeatures = _class.instanceMethodId(
    r"getParserFeatures",
    r"()I",
  );

  /// from: public final int getParserFeatures()
  int getParserFeatures() {
    return _id_getParserFeatures(this, const jni.jintType(), []);
  }

  static final _id_getGeneratorFeatures = _class.instanceMethodId(
    r"getGeneratorFeatures",
    r"()I",
  );

  /// from: public final int getGeneratorFeatures()
  int getGeneratorFeatures() {
    return _id_getGeneratorFeatures(this, const jni.jintType(), []);
  }

  static final _id_getFormatParserFeatures = _class.instanceMethodId(
    r"getFormatParserFeatures",
    r"()I",
  );

  /// from: public int getFormatParserFeatures()
  int getFormatParserFeatures() {
    return _id_getFormatParserFeatures(this, const jni.jintType(), []);
  }

  static final _id_getFormatGeneratorFeatures = _class.instanceMethodId(
    r"getFormatGeneratorFeatures",
    r"()I",
  );

  /// from: public int getFormatGeneratorFeatures()
  int getFormatGeneratorFeatures() {
    return _id_getFormatGeneratorFeatures(this, const jni.jintType(), []);
  }

  static final _id_configure1 = _class.instanceMethodId(
    r"configure",
    r"(Lcom/fasterxml/jackson/core/JsonParser$Feature;Z)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public final com.fasterxml.jackson.core.JsonFactory configure(com.fasterxml.jackson.core.JsonParser.Feature f, boolean state)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for enabling or disabling specified parser feature
  /// (check JsonParser.Feature for list of features)
  ///@param f Feature to enable/disable
  ///@param state Whether to enable or disable the feature
  ///@return This factory instance (to allow call chaining)
  JsonFactory configure1(
    jsonparser_.JsonParser_Feature f,
    bool state,
  ) {
    return _id_configure1(
        this, const $JsonFactoryType(), [f.reference.pointer, state ? 1 : 0]);
  }

  static final _id_enable1 = _class.instanceMethodId(
    r"enable",
    r"(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory enable(com.fasterxml.jackson.core.JsonParser.Feature f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for enabling specified parser feature
  /// (check JsonParser.Feature for list of features)
  ///@param f Feature to enable
  ///@return This factory instance (to allow call chaining)
  JsonFactory enable1(
    jsonparser_.JsonParser_Feature f,
  ) {
    return _id_enable1(this, const $JsonFactoryType(), [f.reference.pointer]);
  }

  static final _id_disable1 = _class.instanceMethodId(
    r"disable",
    r"(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory disable(com.fasterxml.jackson.core.JsonParser.Feature f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for disabling specified parser features
  /// (check JsonParser.Feature for list of features)
  ///@param f Feature to disable
  ///@return This factory instance (to allow call chaining)
  JsonFactory disable1(
    jsonparser_.JsonParser_Feature f,
  ) {
    return _id_disable1(this, const $JsonFactoryType(), [f.reference.pointer]);
  }

  static final _id_isEnabled1 = _class.instanceMethodId(
    r"isEnabled",
    r"(Lcom/fasterxml/jackson/core/JsonParser$Feature;)Z",
  );

  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.JsonParser.Feature f)
  ///
  /// Method for checking if the specified parser feature is enabled.
  ///@param f Feature to check
  ///@return True if specified feature is enabled
  bool isEnabled1(
    jsonparser_.JsonParser_Feature f,
  ) {
    return _id_isEnabled1(
        this, const jni.jbooleanType(), [f.reference.pointer]);
  }

  static final _id_isEnabled2 = _class.instanceMethodId(
    r"isEnabled",
    r"(Lcom/fasterxml/jackson/core/StreamReadFeature;)Z",
  );

  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.StreamReadFeature f)
  ///
  /// Method for checking if the specified stream read feature is enabled.
  ///@param f Feature to check
  ///@return True if specified feature is enabled
  ///@since 2.10
  bool isEnabled2(
    jni.JObject f,
  ) {
    return _id_isEnabled2(
        this, const jni.jbooleanType(), [f.reference.pointer]);
  }

  static final _id_getInputDecorator = _class.instanceMethodId(
    r"getInputDecorator",
    r"()Lcom/fasterxml/jackson/core/io/InputDecorator;",
  );

  /// from: public com.fasterxml.jackson.core.io.InputDecorator getInputDecorator()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for getting currently configured input decorator (if any;
  /// there is no default decorator).
  ///@return InputDecorator configured, if any
  jni.JObject getInputDecorator() {
    return _id_getInputDecorator(this, const jni.JObjectType(), []);
  }

  static final _id_setInputDecorator = _class.instanceMethodId(
    r"setInputDecorator",
    r"(Lcom/fasterxml/jackson/core/io/InputDecorator;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory setInputDecorator(com.fasterxml.jackson.core.io.InputDecorator d)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for overriding currently configured input decorator
  ///@param d Decorator to configure for this factory, if any ({@code null} if none)
  ///@return This factory instance (to allow call chaining)
  ///@deprecated Since 2.10 use JsonFactoryBuilder\#inputDecorator(InputDecorator) instead
  JsonFactory setInputDecorator(
    jni.JObject d,
  ) {
    return _id_setInputDecorator(
        this, const $JsonFactoryType(), [d.reference.pointer]);
  }

  static final _id_configure2 = _class.instanceMethodId(
    r"configure",
    r"(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;Z)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public final com.fasterxml.jackson.core.JsonFactory configure(com.fasterxml.jackson.core.JsonGenerator.Feature f, boolean state)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for enabling or disabling specified generator feature
  /// (check JsonGenerator.Feature for list of features)
  ///@param f Feature to enable/disable
  ///@param state Whether to enable or disable the feature
  ///@return This factory instance (to allow call chaining)
  JsonFactory configure2(
    jni.JObject f,
    bool state,
  ) {
    return _id_configure2(
        this, const $JsonFactoryType(), [f.reference.pointer, state ? 1 : 0]);
  }

  static final _id_enable2 = _class.instanceMethodId(
    r"enable",
    r"(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory enable(com.fasterxml.jackson.core.JsonGenerator.Feature f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for enabling specified generator features
  /// (check JsonGenerator.Feature for list of features)
  ///@param f Feature to enable
  ///@return This factory instance (to allow call chaining)
  JsonFactory enable2(
    jni.JObject f,
  ) {
    return _id_enable2(this, const $JsonFactoryType(), [f.reference.pointer]);
  }

  static final _id_disable2 = _class.instanceMethodId(
    r"disable",
    r"(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory disable(com.fasterxml.jackson.core.JsonGenerator.Feature f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for disabling specified generator feature
  /// (check JsonGenerator.Feature for list of features)
  ///@param f Feature to disable
  ///@return This factory instance (to allow call chaining)
  JsonFactory disable2(
    jni.JObject f,
  ) {
    return _id_disable2(this, const $JsonFactoryType(), [f.reference.pointer]);
  }

  static final _id_isEnabled3 = _class.instanceMethodId(
    r"isEnabled",
    r"(Lcom/fasterxml/jackson/core/JsonGenerator$Feature;)Z",
  );

  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.JsonGenerator.Feature f)
  ///
  /// Check whether specified generator feature is enabled.
  ///@param f Feature to check
  ///@return Whether specified feature is enabled
  bool isEnabled3(
    jni.JObject f,
  ) {
    return _id_isEnabled3(
        this, const jni.jbooleanType(), [f.reference.pointer]);
  }

  static final _id_isEnabled4 = _class.instanceMethodId(
    r"isEnabled",
    r"(Lcom/fasterxml/jackson/core/StreamWriteFeature;)Z",
  );

  /// from: public final boolean isEnabled(com.fasterxml.jackson.core.StreamWriteFeature f)
  ///
  /// Check whether specified stream write feature is enabled.
  ///@param f Feature to check
  ///@return Whether specified feature is enabled
  ///@since 2.10
  bool isEnabled4(
    jni.JObject f,
  ) {
    return _id_isEnabled4(
        this, const jni.jbooleanType(), [f.reference.pointer]);
  }

  static final _id_getCharacterEscapes = _class.instanceMethodId(
    r"getCharacterEscapes",
    r"()Lcom/fasterxml/jackson/core/io/CharacterEscapes;",
  );

  /// from: public com.fasterxml.jackson.core.io.CharacterEscapes getCharacterEscapes()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for accessing custom escapes factory uses for JsonGenerators
  /// it creates.
  ///@return Configured {@code CharacterEscapes}, if any; {@code null} if none
  jni.JObject getCharacterEscapes() {
    return _id_getCharacterEscapes(this, const jni.JObjectType(), []);
  }

  static final _id_setCharacterEscapes = _class.instanceMethodId(
    r"setCharacterEscapes",
    r"(Lcom/fasterxml/jackson/core/io/CharacterEscapes;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory setCharacterEscapes(com.fasterxml.jackson.core.io.CharacterEscapes esc)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for defining custom escapes factory uses for JsonGenerators
  /// it creates.
  ///@param esc CharaterEscapes to set (or {@code null} for "none")
  ///@return This factory instance (to allow call chaining)
  JsonFactory setCharacterEscapes(
    jni.JObject esc,
  ) {
    return _id_setCharacterEscapes(
        this, const $JsonFactoryType(), [esc.reference.pointer]);
  }

  static final _id_getOutputDecorator = _class.instanceMethodId(
    r"getOutputDecorator",
    r"()Lcom/fasterxml/jackson/core/io/OutputDecorator;",
  );

  /// from: public com.fasterxml.jackson.core.io.OutputDecorator getOutputDecorator()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for getting currently configured output decorator (if any;
  /// there is no default decorator).
  ///@return OutputDecorator configured for generators factory creates, if any;
  ///    {@code null} if none.
  jni.JObject getOutputDecorator() {
    return _id_getOutputDecorator(this, const jni.JObjectType(), []);
  }

  static final _id_setOutputDecorator = _class.instanceMethodId(
    r"setOutputDecorator",
    r"(Lcom/fasterxml/jackson/core/io/OutputDecorator;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory setOutputDecorator(com.fasterxml.jackson.core.io.OutputDecorator d)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for overriding currently configured output decorator
  ///@return This factory instance (to allow call chaining)
  ///@param d Output decorator to use, if any
  ///@deprecated Since 2.10 use JsonFactoryBuilder\#outputDecorator(OutputDecorator) instead
  JsonFactory setOutputDecorator(
    jni.JObject d,
  ) {
    return _id_setOutputDecorator(
        this, const $JsonFactoryType(), [d.reference.pointer]);
  }

  static final _id_setRootValueSeparator = _class.instanceMethodId(
    r"setRootValueSeparator",
    r"(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory setRootValueSeparator(java.lang.String sep)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method that allows overriding String used for separating root-level
  /// JSON values (default is single space character)
  ///@param sep Separator to use, if any; null means that no separator is
  ///   automatically added
  ///@return This factory instance (to allow call chaining)
  JsonFactory setRootValueSeparator(
    jni.JString sep,
  ) {
    return _id_setRootValueSeparator(
        this, const $JsonFactoryType(), [sep.reference.pointer]);
  }

  static final _id_getRootValueSeparator = _class.instanceMethodId(
    r"getRootValueSeparator",
    r"()Ljava/lang/String;",
  );

  /// from: public java.lang.String getRootValueSeparator()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// @return Root value separator configured, if any
  jni.JString getRootValueSeparator() {
    return _id_getRootValueSeparator(this, const jni.JStringType(), []);
  }

  static final _id_setCodec = _class.instanceMethodId(
    r"setCodec",
    r"(Lcom/fasterxml/jackson/core/ObjectCodec;)Lcom/fasterxml/jackson/core/JsonFactory;",
  );

  /// from: public com.fasterxml.jackson.core.JsonFactory setCodec(com.fasterxml.jackson.core.ObjectCodec oc)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for associating a ObjectCodec (typically
  /// a <code>com.fasterxml.jackson.databind.ObjectMapper</code>)
  /// with this factory (and more importantly, parsers and generators
  /// it constructs). This is needed to use data-binding methods
  /// of JsonParser and JsonGenerator instances.
  ///@param oc Codec to use
  ///@return This factory instance (to allow call chaining)
  JsonFactory setCodec(
    jni.JObject oc,
  ) {
    return _id_setCodec(this, const $JsonFactoryType(), [oc.reference.pointer]);
  }

  static final _id_getCodec = _class.instanceMethodId(
    r"getCodec",
    r"()Lcom/fasterxml/jackson/core/ObjectCodec;",
  );

  /// from: public com.fasterxml.jackson.core.ObjectCodec getCodec()
  /// The returned object must be released after use, by calling the [release] method.
  jni.JObject getCodec() {
    return _id_getCodec(this, const jni.JObjectType(), []);
  }

  static final _id_createParser = _class.instanceMethodId(
    r"createParser",
    r"(Ljava/io/File;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.File f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON parser instance to parse
  /// contents of specified file.
  ///
  ///
  /// Encoding is auto-detected from contents according to JSON
  /// specification recommended mechanism. Json specification
  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
  /// so auto-detection implemented only for this charsets.
  /// For other charsets use \#createParser(java.io.Reader).
  ///
  ///
  /// Underlying input stream (needed for reading contents)
  /// will be __owned__ (and managed, i.e. closed as need be) by
  /// the parser, since caller has no access to it.
  ///@param f File that contains JSON content to parse
  ///@since 2.1
  jsonparser_.JsonParser createParser(
    jni.JObject f,
  ) {
    return _id_createParser(
        this, const jsonparser_.$JsonParserType(), [f.reference.pointer]);
  }

  static final _id_createParser1 = _class.instanceMethodId(
    r"createParser",
    r"(Ljava/net/URL;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.net.URL url)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON parser instance to parse
  /// contents of resource reference by given URL.
  ///
  /// Encoding is auto-detected from contents according to JSON
  /// specification recommended mechanism. Json specification
  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
  /// so auto-detection implemented only for this charsets.
  /// For other charsets use \#createParser(java.io.Reader).
  ///
  /// Underlying input stream (needed for reading contents)
  /// will be __owned__ (and managed, i.e. closed as need be) by
  /// the parser, since caller has no access to it.
  ///@param url URL pointing to resource that contains JSON content to parse
  ///@since 2.1
  jsonparser_.JsonParser createParser1(
    jni.JObject url,
  ) {
    return _id_createParser1(
        this, const jsonparser_.$JsonParserType(), [url.reference.pointer]);
  }

  static final _id_createParser2 = _class.instanceMethodId(
    r"createParser",
    r"(Ljava/io/InputStream;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.InputStream in)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON parser instance to parse
  /// the contents accessed via specified input stream.
  ///
  /// The input stream will __not be owned__ by
  /// the parser, it will still be managed (i.e. closed if
  /// end-of-stream is reacher, or parser close method called)
  /// if (and only if) com.fasterxml.jackson.core.StreamReadFeature\#AUTO_CLOSE_SOURCE
  /// is enabled.
  ///
  ///
  /// Note: no encoding argument is taken since it can always be
  /// auto-detected as suggested by JSON RFC. Json specification
  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
  /// so auto-detection implemented only for this charsets.
  /// For other charsets use \#createParser(java.io.Reader).
  ///@param in InputStream to use for reading JSON content to parse
  ///@since 2.1
  jsonparser_.JsonParser createParser2(
    jni.JObject in0,
  ) {
    return _id_createParser2(
        this, const jsonparser_.$JsonParserType(), [in0.reference.pointer]);
  }

  static final _id_createParser3 = _class.instanceMethodId(
    r"createParser",
    r"(Ljava/io/Reader;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.Reader r)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// the contents accessed via specified Reader.
  ///
  /// The read stream will __not be owned__ by
  /// the parser, it will still be managed (i.e. closed if
  /// end-of-stream is reacher, or parser close method called)
  /// if (and only if) com.fasterxml.jackson.core.StreamReadFeature\#AUTO_CLOSE_SOURCE
  /// is enabled.
  ///@param r Reader to use for reading JSON content to parse
  ///@since 2.1
  jsonparser_.JsonParser createParser3(
    jni.JObject r,
  ) {
    return _id_createParser3(
        this, const jsonparser_.$JsonParserType(), [r.reference.pointer]);
  }

  static final _id_createParser4 = _class.instanceMethodId(
    r"createParser",
    r"([B)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(byte[] data)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// the contents of given byte array.
  ///@since 2.1
  jsonparser_.JsonParser createParser4(
    jni.JArray<jni.jbyte> data,
  ) {
    return _id_createParser4(
        this, const jsonparser_.$JsonParserType(), [data.reference.pointer]);
  }

  static final _id_createParser5 = _class.instanceMethodId(
    r"createParser",
    r"([BII)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(byte[] data, int offset, int len)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// the contents of given byte array.
  ///@param data Buffer that contains data to parse
  ///@param offset Offset of the first data byte within buffer
  ///@param len Length of contents to parse within buffer
  ///@since 2.1
  jsonparser_.JsonParser createParser5(
    jni.JArray<jni.jbyte> data,
    int offset,
    int len,
  ) {
    return _id_createParser5(this, const jsonparser_.$JsonParserType(),
        [data.reference.pointer, jni.JValueInt(offset), jni.JValueInt(len)]);
  }

  static final _id_createParser6 = _class.instanceMethodId(
    r"createParser",
    r"(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.lang.String content)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// contents of given String.
  ///@since 2.1
  jsonparser_.JsonParser createParser6(
    jni.JString content,
  ) {
    return _id_createParser6(
        this, const jsonparser_.$JsonParserType(), [content.reference.pointer]);
  }

  static final _id_createParser7 = _class.instanceMethodId(
    r"createParser",
    r"([C)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(char[] content)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// contents of given char array.
  ///@since 2.4
  jsonparser_.JsonParser createParser7(
    jni.JArray<jni.jchar> content,
  ) {
    return _id_createParser7(
        this, const jsonparser_.$JsonParserType(), [content.reference.pointer]);
  }

  static final _id_createParser8 = _class.instanceMethodId(
    r"createParser",
    r"([CII)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(char[] content, int offset, int len)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing contents of given char array.
  ///@since 2.4
  jsonparser_.JsonParser createParser8(
    jni.JArray<jni.jchar> content,
    int offset,
    int len,
  ) {
    return _id_createParser8(this, const jsonparser_.$JsonParserType(),
        [content.reference.pointer, jni.JValueInt(offset), jni.JValueInt(len)]);
  }

  static final _id_createParser9 = _class.instanceMethodId(
    r"createParser",
    r"(Ljava/io/DataInput;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createParser(java.io.DataInput in)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Optional method for constructing parser for reading contents from specified DataInput
  /// instance.
  ///
  /// If this factory does not support DataInput as source,
  /// will throw UnsupportedOperationException
  ///@since 2.8
  jsonparser_.JsonParser createParser9(
    jni.JObject in0,
  ) {
    return _id_createParser9(
        this, const jsonparser_.$JsonParserType(), [in0.reference.pointer]);
  }

  static final _id_createNonBlockingByteArrayParser = _class.instanceMethodId(
    r"createNonBlockingByteArrayParser",
    r"()Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createNonBlockingByteArrayParser()
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Optional method for constructing parser for non-blocking parsing
  /// via com.fasterxml.jackson.core.async.ByteArrayFeeder
  /// interface (accessed using JsonParser\#getNonBlockingInputFeeder()
  /// from constructed instance).
  ///
  /// If this factory does not support non-blocking parsing (either at all,
  /// or from byte array),
  /// will throw UnsupportedOperationException.
  ///
  /// Note that JSON-backed factory only supports parsing of UTF-8 encoded JSON content
  /// (and US-ASCII since it is proper subset); other encodings are not supported
  /// at this point.
  ///@since 2.9
  jsonparser_.JsonParser createNonBlockingByteArrayParser() {
    return _id_createNonBlockingByteArrayParser(
        this, const jsonparser_.$JsonParserType(), []);
  }

  static final _id_createGenerator = _class.instanceMethodId(
    r"createGenerator",
    r"(Ljava/io/OutputStream;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.OutputStream out, com.fasterxml.jackson.core.JsonEncoding enc)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON generator for writing JSON content
  /// using specified output stream.
  /// Encoding to use must be specified, and needs to be one of available
  /// types (as per JSON specification).
  ///
  /// Underlying stream __is NOT owned__ by the generator constructed,
  /// so that generator will NOT close the output stream when
  /// JsonGenerator\#close is called (unless auto-closing
  /// feature,
  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET
  /// is enabled).
  /// Using application needs to close it explicitly if this is the case.
  ///
  /// Note: there are formats that use fixed encoding (like most binary data formats)
  /// and that ignore passed in encoding.
  ///@param out OutputStream to use for writing JSON content
  ///@param enc Character encoding to use
  ///@since 2.1
  jni.JObject createGenerator(
    jni.JObject out,
    jni.JObject enc,
  ) {
    return _id_createGenerator(this, const jni.JObjectType(),
        [out.reference.pointer, enc.reference.pointer]);
  }

  static final _id_createGenerator1 = _class.instanceMethodId(
    r"createGenerator",
    r"(Ljava/io/OutputStream;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.OutputStream out)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Convenience method for constructing generator that uses default
  /// encoding of the format (UTF-8 for JSON and most other data formats).
  ///
  /// Note: there are formats that use fixed encoding (like most binary data formats).
  ///@since 2.1
  jni.JObject createGenerator1(
    jni.JObject out,
  ) {
    return _id_createGenerator1(
        this, const jni.JObjectType(), [out.reference.pointer]);
  }

  static final _id_createGenerator2 = _class.instanceMethodId(
    r"createGenerator",
    r"(Ljava/io/Writer;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.Writer w)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON generator for writing JSON content
  /// using specified Writer.
  ///
  /// Underlying stream __is NOT owned__ by the generator constructed,
  /// so that generator will NOT close the Reader when
  /// JsonGenerator\#close is called (unless auto-closing
  /// feature,
  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET is enabled).
  /// Using application needs to close it explicitly.
  ///@since 2.1
  ///@param w Writer to use for writing JSON content
  jni.JObject createGenerator2(
    jni.JObject w,
  ) {
    return _id_createGenerator2(
        this, const jni.JObjectType(), [w.reference.pointer]);
  }

  static final _id_createGenerator3 = _class.instanceMethodId(
    r"createGenerator",
    r"(Ljava/io/File;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.File f, com.fasterxml.jackson.core.JsonEncoding enc)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON generator for writing JSON content
  /// to specified file, overwriting contents it might have (or creating
  /// it if such file does not yet exist).
  /// Encoding to use must be specified, and needs to be one of available
  /// types (as per JSON specification).
  ///
  /// Underlying stream __is owned__ by the generator constructed,
  /// i.e. generator will handle closing of file when
  /// JsonGenerator\#close is called.
  ///@param f File to write contents to
  ///@param enc Character encoding to use
  ///@since 2.1
  jni.JObject createGenerator3(
    jni.JObject f,
    jni.JObject enc,
  ) {
    return _id_createGenerator3(this, const jni.JObjectType(),
        [f.reference.pointer, enc.reference.pointer]);
  }

  static final _id_createGenerator4 = _class.instanceMethodId(
    r"createGenerator",
    r"(Ljava/io/DataOutput;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.DataOutput out, com.fasterxml.jackson.core.JsonEncoding enc)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing generator for writing content using specified
  /// DataOutput instance.
  ///@since 2.8
  jni.JObject createGenerator4(
    jni.JObject out,
    jni.JObject enc,
  ) {
    return _id_createGenerator4(this, const jni.JObjectType(),
        [out.reference.pointer, enc.reference.pointer]);
  }

  static final _id_createGenerator5 = _class.instanceMethodId(
    r"createGenerator",
    r"(Ljava/io/DataOutput;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createGenerator(java.io.DataOutput out)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Convenience method for constructing generator that uses default
  /// encoding of the format (UTF-8 for JSON and most other data formats).
  ///
  /// Note: there are formats that use fixed encoding (like most binary data formats).
  ///@since 2.8
  jni.JObject createGenerator5(
    jni.JObject out,
  ) {
    return _id_createGenerator5(
        this, const jni.JObjectType(), [out.reference.pointer]);
  }

  static final _id_createJsonParser = _class.instanceMethodId(
    r"createJsonParser",
    r"(Ljava/io/File;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.io.File f)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON parser instance to parse
  /// contents of specified file.
  ///
  /// Encoding is auto-detected from contents according to JSON
  /// specification recommended mechanism. Json specification
  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
  /// so auto-detection implemented only for this charsets.
  /// For other charsets use \#createParser(java.io.Reader).
  ///
  ///
  /// Underlying input stream (needed for reading contents)
  /// will be __owned__ (and managed, i.e. closed as need be) by
  /// the parser, since caller has no access to it.
  ///@param f File that contains JSON content to parse
  ///@return Parser constructed
  ///@throws IOException if parser initialization fails due to I/O (read) problem
  ///@throws JsonParseException if parser initialization fails due to content decoding problem
  ///@deprecated Since 2.2, use \#createParser(File) instead.
  jsonparser_.JsonParser createJsonParser(
    jni.JObject f,
  ) {
    return _id_createJsonParser(
        this, const jsonparser_.$JsonParserType(), [f.reference.pointer]);
  }

  static final _id_createJsonParser1 = _class.instanceMethodId(
    r"createJsonParser",
    r"(Ljava/net/URL;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.net.URL url)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON parser instance to parse
  /// contents of resource reference by given URL.
  ///
  /// Encoding is auto-detected from contents according to JSON
  /// specification recommended mechanism. Json specification
  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
  /// so auto-detection implemented only for this charsets.
  /// For other charsets use \#createParser(java.io.Reader).
  ///
  /// Underlying input stream (needed for reading contents)
  /// will be __owned__ (and managed, i.e. closed as need be) by
  /// the parser, since caller has no access to it.
  ///@param url URL pointing to resource that contains JSON content to parse
  ///@return Parser constructed
  ///@throws IOException if parser initialization fails due to I/O (read) problem
  ///@throws JsonParseException if parser initialization fails due to content decoding problem
  ///@deprecated Since 2.2, use \#createParser(URL) instead.
  jsonparser_.JsonParser createJsonParser1(
    jni.JObject url,
  ) {
    return _id_createJsonParser1(
        this, const jsonparser_.$JsonParserType(), [url.reference.pointer]);
  }

  static final _id_createJsonParser2 = _class.instanceMethodId(
    r"createJsonParser",
    r"(Ljava/io/InputStream;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.io.InputStream in)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON parser instance to parse
  /// the contents accessed via specified input stream.
  ///
  /// The input stream will __not be owned__ by
  /// the parser, it will still be managed (i.e. closed if
  /// end-of-stream is reacher, or parser close method called)
  /// if (and only if) com.fasterxml.jackson.core.JsonParser.Feature\#AUTO_CLOSE_SOURCE
  /// is enabled.
  ///
  ///
  /// Note: no encoding argument is taken since it can always be
  /// auto-detected as suggested by JSON RFC. Json specification
  /// supports only UTF-8, UTF-16 and UTF-32 as valid encodings,
  /// so auto-detection implemented only for this charsets.
  /// For other charsets use \#createParser(java.io.Reader).
  ///@param in InputStream to use for reading JSON content to parse
  ///@return Parser constructed
  ///@throws IOException if parser initialization fails due to I/O (read) problem
  ///@throws JsonParseException if parser initialization fails due to content decoding problem
  ///@deprecated Since 2.2, use \#createParser(InputStream) instead.
  jsonparser_.JsonParser createJsonParser2(
    jni.JObject in0,
  ) {
    return _id_createJsonParser2(
        this, const jsonparser_.$JsonParserType(), [in0.reference.pointer]);
  }

  static final _id_createJsonParser3 = _class.instanceMethodId(
    r"createJsonParser",
    r"(Ljava/io/Reader;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.io.Reader r)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// the contents accessed via specified Reader.
  ///
  /// The read stream will __not be owned__ by
  /// the parser, it will still be managed (i.e. closed if
  /// end-of-stream is reacher, or parser close method called)
  /// if (and only if) com.fasterxml.jackson.core.JsonParser.Feature\#AUTO_CLOSE_SOURCE
  /// is enabled.
  ///@param r Reader to use for reading JSON content to parse
  ///@return Parser constructed
  ///@throws IOException if parser initialization fails due to I/O (read) problem
  ///@throws JsonParseException if parser initialization fails due to content decoding problem
  ///@deprecated Since 2.2, use \#createParser(Reader) instead.
  jsonparser_.JsonParser createJsonParser3(
    jni.JObject r,
  ) {
    return _id_createJsonParser3(
        this, const jsonparser_.$JsonParserType(), [r.reference.pointer]);
  }

  static final _id_createJsonParser4 = _class.instanceMethodId(
    r"createJsonParser",
    r"([B)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(byte[] data)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing the contents of given byte array.
  ///@param data Input content to parse
  ///@return Parser constructed
  ///@throws IOException if parser initialization fails due to I/O (read) problem
  ///@throws JsonParseException if parser initialization fails due to content decoding problem
  ///@deprecated Since 2.2, use \#createParser(byte[]) instead.
  jsonparser_.JsonParser createJsonParser4(
    jni.JArray<jni.jbyte> data,
  ) {
    return _id_createJsonParser4(
        this, const jsonparser_.$JsonParserType(), [data.reference.pointer]);
  }

  static final _id_createJsonParser5 = _class.instanceMethodId(
    r"createJsonParser",
    r"([BII)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(byte[] data, int offset, int len)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// the contents of given byte array.
  ///@param data Buffer that contains data to parse
  ///@param offset Offset of the first data byte within buffer
  ///@param len Length of contents to parse within buffer
  ///@return Parser constructed
  ///@throws IOException if parser initialization fails due to I/O (read) problem
  ///@throws JsonParseException if parser initialization fails due to content decoding problem
  ///@deprecated Since 2.2, use \#createParser(byte[],int,int) instead.
  jsonparser_.JsonParser createJsonParser5(
    jni.JArray<jni.jbyte> data,
    int offset,
    int len,
  ) {
    return _id_createJsonParser5(this, const jsonparser_.$JsonParserType(),
        [data.reference.pointer, jni.JValueInt(offset), jni.JValueInt(len)]);
  }

  static final _id_createJsonParser6 = _class.instanceMethodId(
    r"createJsonParser",
    r"(Ljava/lang/String;)Lcom/fasterxml/jackson/core/JsonParser;",
  );

  /// from: public com.fasterxml.jackson.core.JsonParser createJsonParser(java.lang.String content)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing parser for parsing
  /// contents of given String.
  ///@param content Input content to parse
  ///@return Parser constructed
  ///@throws IOException if parser initialization fails due to I/O (read) problem
  ///@throws JsonParseException if parser initialization fails due to content decoding problem
  ///@deprecated Since 2.2, use \#createParser(String) instead.
  jsonparser_.JsonParser createJsonParser6(
    jni.JString content,
  ) {
    return _id_createJsonParser6(
        this, const jsonparser_.$JsonParserType(), [content.reference.pointer]);
  }

  static final _id_createJsonGenerator = _class.instanceMethodId(
    r"createJsonGenerator",
    r"(Ljava/io/OutputStream;Lcom/fasterxml/jackson/core/JsonEncoding;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createJsonGenerator(java.io.OutputStream out, com.fasterxml.jackson.core.JsonEncoding enc)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON generator for writing JSON content
  /// using specified output stream.
  /// Encoding to use must be specified, and needs to be one of available
  /// types (as per JSON specification).
  ///
  /// Underlying stream __is NOT owned__ by the generator constructed,
  /// so that generator will NOT close the output stream when
  /// JsonGenerator\#close is called (unless auto-closing
  /// feature,
  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET
  /// is enabled).
  /// Using application needs to close it explicitly if this is the case.
  ///
  /// Note: there are formats that use fixed encoding (like most binary data formats)
  /// and that ignore passed in encoding.
  ///@param out OutputStream to use for writing JSON content
  ///@param enc Character encoding to use
  ///@return Generator constructed
  ///@throws IOException if parser initialization fails due to I/O (write) problem
  ///@deprecated Since 2.2, use \#createGenerator(OutputStream, JsonEncoding) instead.
  jni.JObject createJsonGenerator(
    jni.JObject out,
    jni.JObject enc,
  ) {
    return _id_createJsonGenerator(this, const jni.JObjectType(),
        [out.reference.pointer, enc.reference.pointer]);
  }

  static final _id_createJsonGenerator1 = _class.instanceMethodId(
    r"createJsonGenerator",
    r"(Ljava/io/Writer;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createJsonGenerator(java.io.Writer out)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Method for constructing JSON generator for writing JSON content
  /// using specified Writer.
  ///
  /// Underlying stream __is NOT owned__ by the generator constructed,
  /// so that generator will NOT close the Reader when
  /// JsonGenerator\#close is called (unless auto-closing
  /// feature,
  /// com.fasterxml.jackson.core.JsonGenerator.Feature\#AUTO_CLOSE_TARGET is enabled).
  /// Using application needs to close it explicitly.
  ///@param out Writer to use for writing JSON content
  ///@return Generator constructed
  ///@throws IOException if parser initialization fails due to I/O (write) problem
  ///@deprecated Since 2.2, use \#createGenerator(Writer) instead.
  jni.JObject createJsonGenerator1(
    jni.JObject out,
  ) {
    return _id_createJsonGenerator1(
        this, const jni.JObjectType(), [out.reference.pointer]);
  }

  static final _id_createJsonGenerator2 = _class.instanceMethodId(
    r"createJsonGenerator",
    r"(Ljava/io/OutputStream;)Lcom/fasterxml/jackson/core/JsonGenerator;",
  );

  /// from: public com.fasterxml.jackson.core.JsonGenerator createJsonGenerator(java.io.OutputStream out)
  /// The returned object must be released after use, by calling the [release] method.
  ///
  /// Convenience method for constructing generator that uses default
  /// encoding of the format (UTF-8 for JSON and most other data formats).
  ///
  /// Note: there are formats that use fixed encoding (like most binary data formats).
  ///@param out OutputStream to use for writing JSON content
  ///@return Generator constructed
  ///@throws IOException if parser initialization fails due to I/O (write) problem
  ///@deprecated Since 2.2, use \#createGenerator(OutputStream) instead.
  jni.JObject createJsonGenerator2(
    jni.JObject out,
  ) {
    return _id_createJsonGenerator2(
        this, const jni.JObjectType(), [out.reference.pointer]);
  }
}

final class $JsonFactoryType extends jni.JObjType<JsonFactory> {
  const $JsonFactoryType();

  @override
  String get signature => r"Lcom/fasterxml/jackson/core/JsonFactory;";

  @override
  JsonFactory fromReference(jni.JReference reference) =>
      JsonFactory.fromReference(reference);

  @override
  jni.JObjType get superType => const jni.JObjectType();

  @override
  final superCount = 1;

  @override
  int get hashCode => ($JsonFactoryType).hashCode;

  @override
  bool operator ==(Object other) {
    return other.runtimeType == ($JsonFactoryType) && other is $JsonFactoryType;
  }
}
