// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.google.protobuf;

import com.google.protobuf.FieldSet.FieldDescriptorLite;
import com.google.protobuf.Internal.EnumLiteMap;
import com.google.protobuf.Internal.EnumVerifier;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.RandomAccess;

/** Helper methods used by schemas. */
@ExperimentalApi
final class SchemaUtil {
  private static final Class<?> GENERATED_MESSAGE_CLASS = getGeneratedMessageClass();
  private static final UnknownFieldSchema<?, ?> PROTO2_UNKNOWN_FIELD_SET_SCHEMA =
      getUnknownFieldSetSchema(false);
  private static final UnknownFieldSchema<?, ?> PROTO3_UNKNOWN_FIELD_SET_SCHEMA =
      getUnknownFieldSetSchema(true);
  private static final UnknownFieldSchema<?, ?> UNKNOWN_FIELD_SET_LITE_SCHEMA =
      new UnknownFieldSetLiteSchema();

  private static final int DEFAULT_LOOK_UP_START_NUMBER = 40;

  private SchemaUtil() {}

  /**
   * Requires that the given message extend {@link com.google.protobuf.GeneratedMessageV3} or {@link
   * GeneratedMessageLite}.
   */
  public static void requireGeneratedMessage(Class<?> messageType) {
    if (!GeneratedMessageLite.class.isAssignableFrom(messageType)
        && GENERATED_MESSAGE_CLASS != null
        && !GENERATED_MESSAGE_CLASS.isAssignableFrom(messageType)) {
      throw new IllegalArgumentException(
          "Message classes must extend GeneratedMessage or GeneratedMessageLite");
    }
  }

  public static void writeDouble(int fieldNumber, double value, Writer writer) throws IOException {
    if (Double.compare(value, 0.0) != 0) {
      writer.writeDouble(fieldNumber, value);
    }
  }

  public static void writeFloat(int fieldNumber, float value, Writer writer) throws IOException {
    if (Float.compare(value, 0.0f) != 0) {
      writer.writeFloat(fieldNumber, value);
    }
  }

  public static void writeInt64(int fieldNumber, long value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeInt64(fieldNumber, value);
    }
  }

  public static void writeUInt64(int fieldNumber, long value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeUInt64(fieldNumber, value);
    }
  }

  public static void writeSInt64(int fieldNumber, long value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeSInt64(fieldNumber, value);
    }
  }

  public static void writeFixed64(int fieldNumber, long value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeFixed64(fieldNumber, value);
    }
  }

  public static void writeSFixed64(int fieldNumber, long value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeSFixed64(fieldNumber, value);
    }
  }

  public static void writeInt32(int fieldNumber, int value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeInt32(fieldNumber, value);
    }
  }

  public static void writeUInt32(int fieldNumber, int value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeUInt32(fieldNumber, value);
    }
  }

  public static void writeSInt32(int fieldNumber, int value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeSInt32(fieldNumber, value);
    }
  }

  public static void writeFixed32(int fieldNumber, int value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeFixed32(fieldNumber, value);
    }
  }

  public static void writeSFixed32(int fieldNumber, int value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeSFixed32(fieldNumber, value);
    }
  }

  public static void writeEnum(int fieldNumber, int value, Writer writer) throws IOException {
    if (value != 0) {
      writer.writeEnum(fieldNumber, value);
    }
  }

  public static void writeBool(int fieldNumber, boolean value, Writer writer) throws IOException {
    if (value) {
      writer.writeBool(fieldNumber, true);
    }
  }

  public static void writeString(int fieldNumber, Object value, Writer writer) throws IOException {
    if (value instanceof String) {
      writeStringInternal(fieldNumber, (String) value, writer);
    } else {
      writeBytes(fieldNumber, (ByteString) value, writer);
    }
  }

  private static void writeStringInternal(int fieldNumber, String value, Writer writer)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeString(fieldNumber, value);
    }
  }

  public static void writeBytes(int fieldNumber, ByteString value, Writer writer)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeBytes(fieldNumber, value);
    }
  }

  public static void writeMessage(int fieldNumber, Object value, Writer writer) throws IOException {
    if (value != null) {
      writer.writeMessage(fieldNumber, value);
    }
  }

  public static void writeDoubleList(
      int fieldNumber, List<Double> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeDoubleList(fieldNumber, value, packed);
    }
  }

  public static void writeFloatList(
      int fieldNumber, List<Float> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeFloatList(fieldNumber, value, packed);
    }
  }

  public static void writeInt64List(
      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeInt64List(fieldNumber, value, packed);
    }
  }

  public static void writeUInt64List(
      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeUInt64List(fieldNumber, value, packed);
    }
  }

  public static void writeSInt64List(
      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeSInt64List(fieldNumber, value, packed);
    }
  }

  public static void writeFixed64List(
      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeFixed64List(fieldNumber, value, packed);
    }
  }

  public static void writeSFixed64List(
      int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeSFixed64List(fieldNumber, value, packed);
    }
  }

  public static void writeInt32List(
      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeInt32List(fieldNumber, value, packed);
    }
  }

  public static void writeUInt32List(
      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeUInt32List(fieldNumber, value, packed);
    }
  }

  public static void writeSInt32List(
      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeSInt32List(fieldNumber, value, packed);
    }
  }

  public static void writeFixed32List(
      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeFixed32List(fieldNumber, value, packed);
    }
  }

  public static void writeSFixed32List(
      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeSFixed32List(fieldNumber, value, packed);
    }
  }

  public static void writeEnumList(
      int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeEnumList(fieldNumber, value, packed);
    }
  }

  public static void writeBoolList(
      int fieldNumber, List<Boolean> value, Writer writer, boolean packed) throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeBoolList(fieldNumber, value, packed);
    }
  }

  public static void writeStringList(int fieldNumber, List<String> value, Writer writer)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeStringList(fieldNumber, value);
    }
  }

  public static void writeBytesList(int fieldNumber, List<ByteString> value, Writer writer)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeBytesList(fieldNumber, value);
    }
  }

  public static void writeMessageList(int fieldNumber, List<?> value, Writer writer)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeMessageList(fieldNumber, value);
    }
  }

  public static void writeMessageList(int fieldNumber, List<?> value, Writer writer, Schema schema)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeMessageList(fieldNumber, value, schema);
    }
  }

  public static void writeLazyFieldList(int fieldNumber, List<?> value, Writer writer)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      for (Object item : value) {
        ((LazyFieldLite) item).writeTo(writer, fieldNumber);
      }
    }
  }

  public static void writeGroupList(int fieldNumber, List<?> value, Writer writer)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeGroupList(fieldNumber, value);
    }
  }

  public static void writeGroupList(int fieldNumber, List<?> value, Writer writer, Schema schema)
      throws IOException {
    if (value != null && !value.isEmpty()) {
      writer.writeGroupList(fieldNumber, value, schema);
    }
  }

  static int computeSizeInt64ListNoTag(List<Long> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = 0;

    if (list instanceof LongArrayList) {
      final LongArrayList primitiveList = (LongArrayList) list;
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeInt64SizeNoTag(primitiveList.getLong(i));
      }
    } else {
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeInt64SizeNoTag(list.get(i));
      }
    }
    return size;
  }

  static int computeSizeInt64List(int fieldNumber, List<Long> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = computeSizeInt64ListNoTag(list);

    if (packed) {
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
    } else {
      return size + (list.size() * CodedOutputStream.computeTagSize(fieldNumber));
    }
  }

  static int computeSizeUInt64ListNoTag(List<Long> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = 0;

    if (list instanceof LongArrayList) {
      final LongArrayList primitiveList = (LongArrayList) list;
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeUInt64SizeNoTag(primitiveList.getLong(i));
      }
    } else {
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeUInt64SizeNoTag(list.get(i));
      }
    }
    return size;
  }

  static int computeSizeUInt64List(int fieldNumber, List<Long> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = computeSizeUInt64ListNoTag(list);

    if (packed) {
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
    } else {
      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
    }
  }

  static int computeSizeSInt64ListNoTag(List<Long> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = 0;

    if (list instanceof LongArrayList) {
      final LongArrayList primitiveList = (LongArrayList) list;
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeSInt64SizeNoTag(primitiveList.getLong(i));
      }
    } else {
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeSInt64SizeNoTag(list.get(i));
      }
    }
    return size;
  }

  static int computeSizeSInt64List(int fieldNumber, List<Long> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = computeSizeSInt64ListNoTag(list);

    if (packed) {
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
    } else {
      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
    }
  }

  static int computeSizeEnumListNoTag(List<Integer> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = 0;

    if (list instanceof IntArrayList) {
      final IntArrayList primitiveList = (IntArrayList) list;
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeEnumSizeNoTag(primitiveList.getInt(i));
      }
    } else {
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeEnumSizeNoTag(list.get(i));
      }
    }
    return size;
  }

  static int computeSizeEnumList(int fieldNumber, List<Integer> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = computeSizeEnumListNoTag(list);

    if (packed) {
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
    } else {
      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
    }
  }

  static int computeSizeInt32ListNoTag(List<Integer> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = 0;

    if (list instanceof IntArrayList) {
      final IntArrayList primitiveList = (IntArrayList) list;
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeInt32SizeNoTag(primitiveList.getInt(i));
      }
    } else {
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeInt32SizeNoTag(list.get(i));
      }
    }
    return size;
  }

  static int computeSizeInt32List(int fieldNumber, List<Integer> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = computeSizeInt32ListNoTag(list);

    if (packed) {
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
    } else {
      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
    }
  }

  static int computeSizeUInt32ListNoTag(List<Integer> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = 0;

    if (list instanceof IntArrayList) {
      final IntArrayList primitiveList = (IntArrayList) list;
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeUInt32SizeNoTag(primitiveList.getInt(i));
      }
    } else {
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeUInt32SizeNoTag(list.get(i));
      }
    }
    return size;
  }

  static int computeSizeUInt32List(int fieldNumber, List<Integer> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = computeSizeUInt32ListNoTag(list);

    if (packed) {
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
    } else {
      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
    }
  }

  static int computeSizeSInt32ListNoTag(List<Integer> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = 0;

    if (list instanceof IntArrayList) {
      final IntArrayList primitiveList = (IntArrayList) list;
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeSInt32SizeNoTag(primitiveList.getInt(i));
      }
    } else {
      for (int i = 0; i < length; i++) {
        size += CodedOutputStream.computeSInt32SizeNoTag(list.get(i));
      }
    }
    return size;
  }

  static int computeSizeSInt32List(int fieldNumber, List<Integer> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }

    int size = computeSizeSInt32ListNoTag(list);

    if (packed) {
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(size);
    } else {
      return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
    }
  }

  static int computeSizeFixed32ListNoTag(List<?> list) {
    return list.size() * WireFormat.FIXED32_SIZE;
  }

  static int computeSizeFixed32List(int fieldNumber, List<?> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    if (packed) {
      int dataSize = length * WireFormat.FIXED32_SIZE;
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
    } else {
      return length * CodedOutputStream.computeFixed32Size(fieldNumber, 0);
    }
  }

  static int computeSizeFixed64ListNoTag(List<?> list) {
    return list.size() * WireFormat.FIXED64_SIZE;
  }

  static int computeSizeFixed64List(int fieldNumber, List<?> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    if (packed) {
      final int dataSize = length * WireFormat.FIXED64_SIZE;
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
    } else {
      return length * CodedOutputStream.computeFixed64Size(fieldNumber, 0);
    }
  }

  static int computeSizeBoolListNoTag(List<?> list) {
    // bools are 1 byte varints
    return list.size();
  }

  static int computeSizeBoolList(int fieldNumber, List<?> list, boolean packed) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    if (packed) {
      // bools are 1 byte varints
      return CodedOutputStream.computeTagSize(fieldNumber)
          + CodedOutputStream.computeLengthDelimitedFieldSize(length);
    } else {
      return length * CodedOutputStream.computeBoolSize(fieldNumber, true);
    }
  }

  static int computeSizeStringList(int fieldNumber, List<?> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
    if (list instanceof LazyStringList) {
      LazyStringList lazyList = ((LazyStringList) list);
      for (int i = 0; i < length; i++) {
        Object value = lazyList.getRaw(i);
        if (value instanceof ByteString) {
          size += CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
        } else {
          size += CodedOutputStream.computeStringSizeNoTag((String) value);
        }
      }
    } else {
      for (int i = 0; i < length; i++) {
        Object value = list.get(i);
        if (value instanceof ByteString) {
          size += CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
        } else {
          size += CodedOutputStream.computeStringSizeNoTag((String) value);
        }
      }
    }
    return size;
  }

  static int computeSizeMessage(int fieldNumber, Object value, Schema schema) {
    if (value instanceof LazyFieldLite) {
      return CodedOutputStream.computeLazyFieldSize(fieldNumber, (LazyFieldLite) value);
    } else {
      return CodedOutputStream.computeMessageSize(fieldNumber, (MessageLite) value, schema);
    }
  }

  static int computeSizeMessageList(int fieldNumber, List<?> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
    for (int i = 0; i < length; i++) {
      Object value = list.get(i);
      if (value instanceof LazyFieldLite) {
        size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite) value);
      } else {
        size += CodedOutputStream.computeMessageSizeNoTag((MessageLite) value);
      }
    }
    return size;
  }

  static int computeSizeMessageList(int fieldNumber, List<?> list, Schema schema) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
    for (int i = 0; i < length; i++) {
      Object value = list.get(i);
      if (value instanceof LazyFieldLite) {
        size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite) value);
      } else {
        size += CodedOutputStream.computeMessageSizeNoTag((MessageLite) value, schema);
      }
    }
    return size;
  }

  static int computeSizeByteStringList(int fieldNumber, List<ByteString> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = length * CodedOutputStream.computeTagSize(fieldNumber);
    for (int i = 0; i < list.size(); i++) {
      size += CodedOutputStream.computeBytesSizeNoTag(list.get(i));
    }
    return size;
  }

  static int computeSizeGroupList(int fieldNumber, List<MessageLite> list) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = 0;
    for (int i = 0; i < length; i++) {
      size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(i));
    }
    return size;
  }

  static int computeSizeGroupList(int fieldNumber, List<MessageLite> list, Schema schema) {
    final int length = list.size();
    if (length == 0) {
      return 0;
    }
    int size = 0;
    for (int i = 0; i < length; i++) {
      size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(i), schema);
    }
    return size;
  }

  /**
   * Determines whether to issue tableswitch or lookupswitch for the mergeFrom method.
   *
   * @see #shouldUseTableSwitch(int, int, int)
   */
  public static boolean shouldUseTableSwitch(FieldInfo[] fields) {
    // Determine whether to issue a tableswitch or a lookupswitch
    // instruction.
    if (fields.length == 0) {
      return false;
    }

    int lo = fields[0].getFieldNumber();
    int hi = fields[fields.length - 1].getFieldNumber();
    return shouldUseTableSwitch(lo, hi, fields.length);
  }

  /**
   * Determines whether to issue tableswitch or lookupswitch for the mergeFrom method. This is based
   * on the <a href=
   * "http://hg.openjdk.java.net/jdk8/jdk8/langtools/file/30db5e0aaf83/src/share/classes/com/sun/tools/javac/jvm/Gen.java#l1159">
   * logic in the JDK</a>.
   *
   * @param lo the lowest fieldNumber contained within the message.
   * @param hi the higest fieldNumber contained within the message.
   * @param numFields the total number of fields in the message.
   * @return {@code true} if tableswitch should be used, rather than lookupswitch.
   */
  public static boolean shouldUseTableSwitch(int lo, int hi, int numFields) {
    if (hi < DEFAULT_LOOK_UP_START_NUMBER) {
      return true;
    }
    long tableSpaceCost = ((long) hi - lo + 1); // words
    long tableTimeCost = 3; // comparisons
    long lookupSpaceCost = 3 + 2 * (long) numFields;
    long lookupTimeCost = 3 + (long) numFields;
    return tableSpaceCost + 3 * tableTimeCost <= lookupSpaceCost + 3 * lookupTimeCost;
  }

  public static UnknownFieldSchema<?, ?> proto2UnknownFieldSetSchema() {
    return PROTO2_UNKNOWN_FIELD_SET_SCHEMA;
  }

  public static UnknownFieldSchema<?, ?> proto3UnknownFieldSetSchema() {
    return PROTO3_UNKNOWN_FIELD_SET_SCHEMA;
  }

  public static UnknownFieldSchema<?, ?> unknownFieldSetLiteSchema() {
    return UNKNOWN_FIELD_SET_LITE_SCHEMA;
  }

  private static UnknownFieldSchema<?, ?> getUnknownFieldSetSchema(boolean proto3) {
    try {
      Class<?> clz = getUnknownFieldSetSchemaClass();
      if (clz == null) {
        return null;
      }
      return (UnknownFieldSchema) clz.getConstructor(boolean.class).newInstance(proto3);
    } catch (Throwable t) {
      return null;
    }
  }

  private static Class<?> getGeneratedMessageClass() {
    try {
      return Class.forName("com.google.protobuf.GeneratedMessageV3");
    } catch (Throwable e) {
      return null;
    }
  }

  private static Class<?> getUnknownFieldSetSchemaClass() {
    try {
      return Class.forName("com.google.protobuf.UnknownFieldSetSchema");
    } catch (Throwable e) {
      return null;
    }
  }

  static Object getMapDefaultEntry(Class<?> clazz, String name) {
    try {
      Class<?> holder =
          Class.forName(clazz.getName() + "$" + toCamelCase(name, true) + "DefaultEntryHolder");
      Field[] fields = holder.getDeclaredFields();
      if (fields.length != 1) {
        throw new IllegalStateException(
            "Unable to look up map field default entry holder class for "
                + name
                + " in "
                + clazz.getName());
      }
      return UnsafeUtil.getStaticObject(fields[0]);
    } catch (Throwable t) {
      throw new RuntimeException(t);
    }
  }

  static String toCamelCase(String name, boolean capNext) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < name.length(); ++i) {
      char c = name.charAt(i);
      // Matches protoc field name function:
      if ('a' <= c && c <= 'z') {
        if (capNext) {
          sb.append((char) (c + ('A' - 'a')));
        } else {
          sb.append(c);
        }
        capNext = false;
      } else if ('A' <= c && c <= 'Z') {
        if (i == 0 && !capNext) {
          // Force first letter to lower-case unless explicitly told to capitalize it.
          sb.append((char) (c - ('A' - 'a')));
        } else {
          sb.append(c);
        }
        capNext = false;
      } else if ('0' <= c && c <= '9') {
        sb.append(c);
        capNext = true;
      } else {
        capNext = true;
      }
    }
    return sb.toString();
  }

  /** Returns true if both are null or both are {@link Object#equals}. */
  static boolean safeEquals(Object a, Object b) {
    return a == b || (a != null && a.equals(b));
  }

  static <T> void mergeMap(MapFieldSchema mapFieldSchema, T message, T o, long offset) {
    Object merged =
        mapFieldSchema.mergeFrom(
            UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(o, offset));
    UnsafeUtil.putObject(message, offset, merged);
  }

  static <T, FT extends FieldDescriptorLite<FT>> void mergeExtensions(
      ExtensionSchema<FT> schema, T message, T other) {
    FieldSet<FT> otherExtensions = schema.getExtensions(other);
    if (!otherExtensions.isEmpty()) {
      FieldSet<FT> messageExtensions = schema.getMutableExtensions(message);
      messageExtensions.mergeFrom(otherExtensions);
    }
  }

  static <T, UT, UB> void mergeUnknownFields(
      UnknownFieldSchema<UT, UB> schema, T message, T other) {
    UT messageUnknowns = schema.getFromMessage(message);
    UT otherUnknowns = schema.getFromMessage(other);
    UT merged = schema.merge(messageUnknowns, otherUnknowns);
    schema.setToMessage(message, merged);
  }

  /** Filters unrecognized enum values in a list. */
  static <UT, UB> UB filterUnknownEnumList(
      int number,
      List<Integer> enumList,
      EnumLiteMap<?> enumMap,
      UB unknownFields,
      UnknownFieldSchema<UT, UB> unknownFieldSchema) {
    if (enumMap == null) {
      return unknownFields;
    }
    // TODO(dweis): Specialize for IntArrayList to avoid boxing.
    if (enumList instanceof RandomAccess) {
      int writePos = 0;
      int size = enumList.size();
      for (int readPos = 0; readPos < size; ++readPos) {
        int enumValue = enumList.get(readPos);
        if (enumMap.findValueByNumber(enumValue) != null) {
          if (readPos != writePos) {
            enumList.set(writePos, enumValue);
          }
          ++writePos;
        } else {
          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
        }
      }
      if (writePos != size) {
        enumList.subList(writePos, size).clear();
      }
    } else {
      for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
        int enumValue = it.next();
        if (enumMap.findValueByNumber(enumValue) == null) {
          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
          it.remove();
        }
      }
    }
    return unknownFields;
  }

  /** Filters unrecognized enum values in a list. */
  static <UT, UB> UB filterUnknownEnumList(
      int number,
      List<Integer> enumList,
      EnumVerifier enumVerifier,
      UB unknownFields,
      UnknownFieldSchema<UT, UB> unknownFieldSchema) {
    if (enumVerifier == null) {
      return unknownFields;
    }
    // TODO(dweis): Specialize for IntArrayList to avoid boxing.
    if (enumList instanceof RandomAccess) {
      int writePos = 0;
      int size = enumList.size();
      for (int readPos = 0; readPos < size; ++readPos) {
        int enumValue = enumList.get(readPos);
        if (enumVerifier.isInRange(enumValue)) {
          if (readPos != writePos) {
            enumList.set(writePos, enumValue);
          }
          ++writePos;
        } else {
          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
        }
      }
      if (writePos != size) {
        enumList.subList(writePos, size).clear();
      }
    } else {
      for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
        int enumValue = it.next();
        if (!enumVerifier.isInRange(enumValue)) {
          unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
          it.remove();
        }
      }
    }
    return unknownFields;
  }

  /** Stores an unrecognized enum value as an unknown value. */
  static <UT, UB> UB storeUnknownEnum(
      int number, int enumValue, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
    if (unknownFields == null) {
      unknownFields = unknownFieldSchema.newBuilder();
    }
    unknownFieldSchema.addVarint(unknownFields, number, enumValue);
    return unknownFields;
  }
}
