// 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.
/** 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 GeneratedMessageV3 or GeneratedMessageLite.
/** * 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 Also:
  • shouldUseTableSwitch(int, int, int)
/** * 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 logic in the JDK.
Params:
  • lo – the lowest fieldNumber contained within the message.
  • hi – the higest fieldNumber contained within the message.
  • numFields – the total number of fields in the message.
Returns:true if tableswitch should be used, rather than lookupswitch.
/** * 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 Object.equals.
/** 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.
/** 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.
/** 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.
/** 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; } }