// 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.startObject(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.startObject(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.endObject();
        return o;
    }
}

