// CHECKSTYLE:OFF Generated code
/*
 * 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.
 */

package androidx.text.emoji.flatbuffer;

import com.google.flatbuffers.FlatBufferBuilder;
import com.google.flatbuffers.Table;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * Automatically generated by the FlatBuffers compiler, do not modify.
 */
@SuppressWarnings("unused")
public final class MetadataItem extends Table {
    public static MetadataItem getRootAsMetadataItem(ByteBuffer _bb) {
        return getRootAsMetadataItem(_bb, new MetadataItem());
    }

    public static MetadataItem getRootAsMetadataItem(ByteBuffer _bb, MetadataItem obj) {
        _bb.order(ByteOrder.LITTLE_ENDIAN);
        return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb));
    }

    public void __init(int _i, ByteBuffer _bb) {
        bb_pos = _i;
        bb = _bb;
    }

    public MetadataItem __assign(int _i, ByteBuffer _bb) {
        __init(_i, _bb);
        return this;
    }

    public int id() {
        int o = __offset(4);
        return o != 0 ? bb.getInt(o + bb_pos) : 0;
    }

    public boolean emojiStyle() {
        int o = __offset(6);
        return o != 0 ? 0 != bb.get(o + bb_pos) : false;
    }

    public short sdkAdded() {
        int o = __offset(8);
        return o != 0 ? bb.getShort(o + bb_pos) : 0;
    }

    public short compatAdded() {
        int o = __offset(10);
        return o != 0 ? bb.getShort(o + bb_pos) : 0;
    }

    public short width() {
        int o = __offset(12);
        return o != 0 ? bb.getShort(o + bb_pos) : 0;
    }

    public short height() {
        int o = __offset(14);
        return o != 0 ? bb.getShort(o + bb_pos) : 0;
    }

    public int codepoints(int j) {
        int o = __offset(16);
        return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0;
    }

    public int codepointsLength() {
        int o = __offset(16);
        return o != 0 ? __vector_len(o) : 0;
    }

    public ByteBuffer codepointsAsByteBuffer() {
        return __vector_as_bytebuffer(16, 4);
    }

    public static int createMetadataItem(FlatBufferBuilder builder,
            int id,
            boolean emojiStyle,
            short sdkAdded,
            short compatAdded,
            short width,
            short height,
            int codepointsOffset) {
        builder.startTable(7);
        MetadataItem.addCodepoints(builder, codepointsOffset);
        MetadataItem.addId(builder, id);
        MetadataItem.addHeight(builder, height);
        MetadataItem.addWidth(builder, width);
        MetadataItem.addCompatAdded(builder, compatAdded);
        MetadataItem.addSdkAdded(builder, sdkAdded);
        MetadataItem.addEmojiStyle(builder, emojiStyle);
        return MetadataItem.endMetadataItem(builder);
    }

    public static void startMetadataItem(FlatBufferBuilder builder) {
        builder.startTable(7);
    }

    public static void addId(FlatBufferBuilder builder, int id) {
        builder.addInt(0, id, 0);
    }

    public static void addEmojiStyle(FlatBufferBuilder builder, boolean emojiStyle) {
        builder.addBoolean(1, emojiStyle, false);
    }

    public static void addSdkAdded(FlatBufferBuilder builder, short sdkAdded) {
        builder.addShort(2, sdkAdded, 0);
    }

    public static void addCompatAdded(FlatBufferBuilder builder, short compatAdded) {
        builder.addShort(3, compatAdded, 0);
    }

    public static void addWidth(FlatBufferBuilder builder, short width) {
        builder.addShort(4, width, 0);
    }

    public static void addHeight(FlatBufferBuilder builder, short height) {
        builder.addShort(5, height, 0);
    }

    public static void addCodepoints(FlatBufferBuilder builder, int codepointsOffset) {
        builder.addOffset(6, codepointsOffset, 0);
    }

    public static int createCodepointsVector(FlatBufferBuilder builder, int[] data) {
        builder.startVector(4, data.length, 4);
        for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]);
        return builder.endVector();
    }

    public static void startCodepointsVector(FlatBufferBuilder builder, int numElems) {
        builder.startVector(4, numElems, 4);
    }

    public static int endMetadataItem(FlatBufferBuilder builder) {
        int o = builder.endTable();
        return o;
    }
}

