// 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 "../../../../_init.dart";

/// from: com.fasterxml.jackson.core.JsonToken
///
/// Enumeration for basic token types used for returning results
/// of parsing JSON content.
class JsonToken extends jni.JObject {
  @override
  late final jni.JObjType<JsonToken> $type = type;

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

  /// The type which includes information such as the signature of this class.
  static const type = $JsonTokenType();
  static final _values =
      jniLookup<ffi.NativeFunction<jni.JniResult Function()>>(
              "JsonToken__values")
          .asFunction<jni.JniResult Function()>();

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

  static final _valueOf = jniLookup<
              ffi
              .NativeFunction<jni.JniResult Function(ffi.Pointer<ffi.Void>)>>(
          "JsonToken__valueOf")
      .asFunction<jni.JniResult Function(ffi.Pointer<ffi.Void>)>();

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

  static final _id = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__id")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final int id()
  int id() {
    return _id(reference.pointer).integer;
  }

  static final _asString = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__asString")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final java.lang.String asString()
  /// The returned object must be released after use, by calling the [release] method.
  jni.JString asString() {
    return _asString(reference.pointer).object(const jni.JStringType());
  }

  static final _asCharArray = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__asCharArray")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final char[] asCharArray()
  /// The returned object must be released after use, by calling the [release] method.
  jni.JArray<jni.jchar> asCharArray() {
    return _asCharArray(reference.pointer)
        .object(const jni.JArrayType(jni.jcharType()));
  }

  static final _asByteArray = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__asByteArray")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final byte[] asByteArray()
  /// The returned object must be released after use, by calling the [release] method.
  jni.JArray<jni.jbyte> asByteArray() {
    return _asByteArray(reference.pointer)
        .object(const jni.JArrayType(jni.jbyteType()));
  }

  static final _isNumeric = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__isNumeric")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final boolean isNumeric()
  ///
  /// @return {@code True} if this token is {@code VALUE_NUMBER_INT} or {@code VALUE_NUMBER_FLOAT},
  ///   {@code false} otherwise
  bool isNumeric() {
    return _isNumeric(reference.pointer).boolean;
  }

  static final _isStructStart = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__isStructStart")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final boolean isStructStart()
  ///
  /// Accessor that is functionally equivalent to:
  /// <code>
  ///    this == JsonToken.START_OBJECT || this == JsonToken.START_ARRAY
  /// </code>
  ///@return {@code True} if this token is {@code START_OBJECT} or {@code START_ARRAY},
  ///   {@code false} otherwise
  ///@since 2.3
  bool isStructStart() {
    return _isStructStart(reference.pointer).boolean;
  }

  static final _isStructEnd = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__isStructEnd")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final boolean isStructEnd()
  ///
  /// Accessor that is functionally equivalent to:
  /// <code>
  ///    this == JsonToken.END_OBJECT || this == JsonToken.END_ARRAY
  /// </code>
  ///@return {@code True} if this token is {@code END_OBJECT} or {@code END_ARRAY},
  ///   {@code false} otherwise
  ///@since 2.3
  bool isStructEnd() {
    return _isStructEnd(reference.pointer).boolean;
  }

  static final _isScalarValue = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__isScalarValue")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final boolean isScalarValue()
  ///
  /// Method that can be used to check whether this token represents
  /// a valid non-structured value. This means all {@code VALUE_xxx} tokens;
  /// excluding {@code START_xxx} and {@code END_xxx} tokens as well
  /// {@code FIELD_NAME}.
  ///@return {@code True} if this token is a scalar value token (one of
  ///   {@code VALUE_xxx} tokens), {@code false} otherwise
  bool isScalarValue() {
    return _isScalarValue(reference.pointer).boolean;
  }

  static final _isBoolean = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                ffi.Pointer<ffi.Void>,
              )>>("JsonToken__isBoolean")
      .asFunction<
          jni.JniResult Function(
            ffi.Pointer<ffi.Void>,
          )>();

  /// from: public final boolean isBoolean()
  ///
  /// @return {@code True} if this token is {@code VALUE_TRUE} or {@code VALUE_FALSE},
  ///   {@code false} otherwise
  bool isBoolean() {
    return _isBoolean(reference.pointer).boolean;
  }
}

final class $JsonTokenType extends jni.JObjType<JsonToken> {
  const $JsonTokenType();

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

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

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

  @override
  final superCount = 1;

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

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