1014 lines
32 KiB
Java
1014 lines
32 KiB
Java
![]() |
// 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
|
||
|
@CheckReturnValue
|
||
|
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) {
|
||
|
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle this
|
||
|
// better.
|
||
|
if (!GeneratedMessageLite.class.isAssignableFrom(messageType)
|
||
|
&& GENERATED_MESSAGE_CLASS != null
|
||
|
&& !GENERATED_MESSAGE_CLASS.isAssignableFrom(messageType)) {
|
||
|
throw new IllegalArgumentException(
|
||
|
"Message classes must extend GeneratedMessageV3 or GeneratedMessageLite");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void writeDouble(int fieldNumber, double value, Writer writer) throws IOException {
|
||
|
if (Double.doubleToRawLongBits(value) != 0) {
|
||
|
writer.writeDouble(fieldNumber, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void writeFloat(int fieldNumber, float value, Writer writer) throws IOException {
|
||
|
if (Float.floatToRawIntBits(value) != 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 highest 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 {
|
||
|
// TODO(b/248560713) decide if we're keeping support for Full in schema classes and handle
|
||
|
// this better.
|
||
|
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. */
|
||
|
@CanIgnoreReturnValue
|
||
|
static <UT, UB> UB filterUnknownEnumList(
|
||
|
Object containerMessage,
|
||
|
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(
|
||
|
containerMessage, 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(
|
||
|
containerMessage, number, enumValue, unknownFields, unknownFieldSchema);
|
||
|
it.remove();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return unknownFields;
|
||
|
}
|
||
|
|
||
|
/** Filters unrecognized enum values in a list. */
|
||
|
@CanIgnoreReturnValue
|
||
|
static <UT, UB> UB filterUnknownEnumList(
|
||
|
Object containerMessage,
|
||
|
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(
|
||
|
containerMessage, 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(
|
||
|
containerMessage, number, enumValue, unknownFields, unknownFieldSchema);
|
||
|
it.remove();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return unknownFields;
|
||
|
}
|
||
|
|
||
|
/** Stores an unrecognized enum value as an unknown value. */
|
||
|
@CanIgnoreReturnValue
|
||
|
static <UT, UB> UB storeUnknownEnum(
|
||
|
Object containerMessage,
|
||
|
int number,
|
||
|
int enumValue,
|
||
|
UB unknownFields,
|
||
|
UnknownFieldSchema<UT, UB> unknownFieldSchema) {
|
||
|
if (unknownFields == null) {
|
||
|
unknownFields = unknownFieldSchema.getBuilderFromMessage(containerMessage);
|
||
|
}
|
||
|
unknownFieldSchema.addVarint(unknownFields, number, enumValue);
|
||
|
return unknownFields;
|
||
|
}
|
||
|
}
|