31 package com.google.protobuf;
36 import java.io.IOException;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.RandomAccess;
44 final class SchemaUtil {
45 private static final Class<?> GENERATED_MESSAGE_CLASS = getGeneratedMessageClass();
46 private static final UnknownFieldSchema<?, ?> PROTO2_UNKNOWN_FIELD_SET_SCHEMA =
47 getUnknownFieldSetSchema(
false);
48 private static final UnknownFieldSchema<?, ?> PROTO3_UNKNOWN_FIELD_SET_SCHEMA =
49 getUnknownFieldSetSchema(
true);
50 private static final UnknownFieldSchema<?, ?> UNKNOWN_FIELD_SET_LITE_SCHEMA =
51 new UnknownFieldSetLiteSchema();
53 private static final int DEFAULT_LOOK_UP_START_NUMBER = 40;
55 private SchemaUtil() {}
61 public static void requireGeneratedMessage(Class<?> messageType) {
62 if (!GeneratedMessageLite.class.isAssignableFrom(messageType)
63 && GENERATED_MESSAGE_CLASS !=
null
64 && !GENERATED_MESSAGE_CLASS.isAssignableFrom(messageType)) {
65 throw new IllegalArgumentException(
66 "Message classes must extend GeneratedMessage or GeneratedMessageLite");
70 public static void writeDouble(
int fieldNumber,
double value, Writer writer)
throws IOException {
72 writer.writeDouble(fieldNumber,
value);
76 public static void writeFloat(
int fieldNumber,
float value, Writer writer)
throws IOException {
78 writer.writeFloat(fieldNumber,
value);
82 public static void writeInt64(
int fieldNumber,
long value, Writer writer)
throws IOException {
84 writer.writeInt64(fieldNumber,
value);
88 public static void writeUInt64(
int fieldNumber,
long value, Writer writer)
throws IOException {
90 writer.writeUInt64(fieldNumber,
value);
94 public static void writeSInt64(
int fieldNumber,
long value, Writer writer)
throws IOException {
96 writer.writeSInt64(fieldNumber,
value);
100 public static void writeFixed64(
int fieldNumber,
long value, Writer writer)
throws IOException {
102 writer.writeFixed64(fieldNumber,
value);
106 public static void writeSFixed64(
int fieldNumber,
long value, Writer writer)
throws IOException {
108 writer.writeSFixed64(fieldNumber,
value);
112 public static void writeInt32(
int fieldNumber,
int value, Writer writer)
throws IOException {
114 writer.writeInt32(fieldNumber,
value);
118 public static void writeUInt32(
int fieldNumber,
int value, Writer writer)
throws IOException {
120 writer.writeUInt32(fieldNumber,
value);
124 public static void writeSInt32(
int fieldNumber,
int value, Writer writer)
throws IOException {
126 writer.writeSInt32(fieldNumber,
value);
130 public static void writeFixed32(
int fieldNumber,
int value, Writer writer)
throws IOException {
132 writer.writeFixed32(fieldNumber,
value);
136 public static void writeSFixed32(
int fieldNumber,
int value, Writer writer)
throws IOException {
138 writer.writeSFixed32(fieldNumber,
value);
142 public static void writeEnum(
int fieldNumber,
int value, Writer writer)
throws IOException {
144 writer.writeEnum(fieldNumber,
value);
148 public static void writeBool(
int fieldNumber,
boolean value, Writer writer)
throws IOException {
150 writer.writeBool(fieldNumber,
true);
154 public static void writeString(
int fieldNumber, Object
value, Writer writer)
throws IOException {
155 if (
value instanceof String) {
156 writeStringInternal(fieldNumber, (String)
value, writer);
158 writeBytes(fieldNumber, (ByteString)
value, writer);
162 private static void writeStringInternal(
int fieldNumber, String
value, Writer writer)
165 writer.writeString(fieldNumber,
value);
169 public static void writeBytes(
int fieldNumber, ByteString
value, Writer writer)
172 writer.writeBytes(fieldNumber,
value);
176 public static void writeMessage(
int fieldNumber, Object
value, Writer writer)
throws IOException {
178 writer.writeMessage(fieldNumber,
value);
182 public static void writeDoubleList(
183 int fieldNumber, List<Double>
value, Writer writer,
boolean packed)
throws IOException {
185 writer.writeDoubleList(fieldNumber,
value, packed);
189 public static void writeFloatList(
190 int fieldNumber, List<Float>
value, Writer writer,
boolean packed)
throws IOException {
192 writer.writeFloatList(fieldNumber,
value, packed);
196 public static void writeInt64List(
197 int fieldNumber, List<Long>
value, Writer writer,
boolean packed)
throws IOException {
199 writer.writeInt64List(fieldNumber,
value, packed);
203 public static void writeUInt64List(
204 int fieldNumber, List<Long>
value, Writer writer,
boolean packed)
throws IOException {
206 writer.writeUInt64List(fieldNumber,
value, packed);
210 public static void writeSInt64List(
211 int fieldNumber, List<Long>
value, Writer writer,
boolean packed)
throws IOException {
213 writer.writeSInt64List(fieldNumber,
value, packed);
217 public static void writeFixed64List(
218 int fieldNumber, List<Long>
value, Writer writer,
boolean packed)
throws IOException {
220 writer.writeFixed64List(fieldNumber,
value, packed);
224 public static void writeSFixed64List(
225 int fieldNumber, List<Long>
value, Writer writer,
boolean packed)
throws IOException {
227 writer.writeSFixed64List(fieldNumber,
value, packed);
231 public static void writeInt32List(
232 int fieldNumber, List<Integer>
value, Writer writer,
boolean packed)
throws IOException {
234 writer.writeInt32List(fieldNumber,
value, packed);
238 public static void writeUInt32List(
239 int fieldNumber, List<Integer>
value, Writer writer,
boolean packed)
throws IOException {
241 writer.writeUInt32List(fieldNumber,
value, packed);
245 public static void writeSInt32List(
246 int fieldNumber, List<Integer>
value, Writer writer,
boolean packed)
throws IOException {
248 writer.writeSInt32List(fieldNumber,
value, packed);
252 public static void writeFixed32List(
253 int fieldNumber, List<Integer>
value, Writer writer,
boolean packed)
throws IOException {
255 writer.writeFixed32List(fieldNumber,
value, packed);
259 public static void writeSFixed32List(
260 int fieldNumber, List<Integer>
value, Writer writer,
boolean packed)
throws IOException {
262 writer.writeSFixed32List(fieldNumber,
value, packed);
266 public static void writeEnumList(
267 int fieldNumber, List<Integer>
value, Writer writer,
boolean packed)
throws IOException {
269 writer.writeEnumList(fieldNumber,
value, packed);
273 public static void writeBoolList(
274 int fieldNumber, List<Boolean>
value, Writer writer,
boolean packed)
throws IOException {
276 writer.writeBoolList(fieldNumber,
value, packed);
280 public static void writeStringList(
int fieldNumber, List<String>
value, Writer writer)
283 writer.writeStringList(fieldNumber,
value);
287 public static void writeBytesList(
int fieldNumber, List<ByteString>
value, Writer writer)
290 writer.writeBytesList(fieldNumber,
value);
294 public static void writeMessageList(
int fieldNumber, List<?>
value, Writer writer)
297 writer.writeMessageList(fieldNumber,
value);
301 public static void writeMessageList(
int fieldNumber, List<?>
value, Writer writer, Schema schema)
304 writer.writeMessageList(fieldNumber,
value, schema);
308 public static void writeLazyFieldList(
int fieldNumber, List<?>
value, Writer writer)
312 ((LazyFieldLite)
item).writeTo(writer, fieldNumber);
317 public static void writeGroupList(
int fieldNumber, List<?>
value, Writer writer)
320 writer.writeGroupList(fieldNumber,
value);
324 public static void writeGroupList(
int fieldNumber, List<?>
value, Writer writer, Schema schema)
327 writer.writeGroupList(fieldNumber,
value, schema);
331 static int computeSizeInt64ListNoTag(List<Long> list) {
332 final int length = list.size();
339 if (list instanceof LongArrayList) {
340 final LongArrayList primitiveList = (LongArrayList) list;
342 size += CodedOutputStream.computeInt64SizeNoTag(primitiveList.getLong(
i));
346 size += CodedOutputStream.computeInt64SizeNoTag(list.get(
i));
352 static int computeSizeInt64List(
int fieldNumber, List<Long> list,
boolean packed) {
353 final int length = list.size();
357 int size = computeSizeInt64ListNoTag(list);
360 return CodedOutputStream.computeTagSize(fieldNumber)
361 + CodedOutputStream.computeLengthDelimitedFieldSize(
size);
363 return size + (list.size() * CodedOutputStream.computeTagSize(fieldNumber));
367 static int computeSizeUInt64ListNoTag(List<Long> list) {
368 final int length = list.size();
375 if (list instanceof LongArrayList) {
376 final LongArrayList primitiveList = (LongArrayList) list;
378 size += CodedOutputStream.computeUInt64SizeNoTag(primitiveList.getLong(
i));
382 size += CodedOutputStream.computeUInt64SizeNoTag(list.get(
i));
388 static int computeSizeUInt64List(
int fieldNumber, List<Long> list,
boolean packed) {
389 final int length = list.size();
393 int size = computeSizeUInt64ListNoTag(list);
396 return CodedOutputStream.computeTagSize(fieldNumber)
397 + CodedOutputStream.computeLengthDelimitedFieldSize(
size);
399 return size + (
length * CodedOutputStream.computeTagSize(fieldNumber));
403 static int computeSizeSInt64ListNoTag(List<Long> list) {
404 final int length = list.size();
411 if (list instanceof LongArrayList) {
412 final LongArrayList primitiveList = (LongArrayList) list;
414 size += CodedOutputStream.computeSInt64SizeNoTag(primitiveList.getLong(
i));
418 size += CodedOutputStream.computeSInt64SizeNoTag(list.get(
i));
424 static int computeSizeSInt64List(
int fieldNumber, List<Long> list,
boolean packed) {
425 final int length = list.size();
429 int size = computeSizeSInt64ListNoTag(list);
432 return CodedOutputStream.computeTagSize(fieldNumber)
433 + CodedOutputStream.computeLengthDelimitedFieldSize(
size);
435 return size + (
length * CodedOutputStream.computeTagSize(fieldNumber));
439 static int computeSizeEnumListNoTag(List<Integer> list) {
440 final int length = list.size();
447 if (list instanceof IntArrayList) {
448 final IntArrayList primitiveList = (IntArrayList) list;
450 size += CodedOutputStream.computeEnumSizeNoTag(primitiveList.getInt(
i));
454 size += CodedOutputStream.computeEnumSizeNoTag(list.get(
i));
460 static int computeSizeEnumList(
int fieldNumber, List<Integer> list,
boolean packed) {
461 final int length = list.size();
465 int size = computeSizeEnumListNoTag(list);
468 return CodedOutputStream.computeTagSize(fieldNumber)
469 + CodedOutputStream.computeLengthDelimitedFieldSize(
size);
471 return size + (
length * CodedOutputStream.computeTagSize(fieldNumber));
475 static int computeSizeInt32ListNoTag(List<Integer> list) {
476 final int length = list.size();
483 if (list instanceof IntArrayList) {
484 final IntArrayList primitiveList = (IntArrayList) list;
486 size += CodedOutputStream.computeInt32SizeNoTag(primitiveList.getInt(
i));
490 size += CodedOutputStream.computeInt32SizeNoTag(list.get(
i));
496 static int computeSizeInt32List(
int fieldNumber, List<Integer> list,
boolean packed) {
497 final int length = list.size();
501 int size = computeSizeInt32ListNoTag(list);
504 return CodedOutputStream.computeTagSize(fieldNumber)
505 + CodedOutputStream.computeLengthDelimitedFieldSize(
size);
507 return size + (
length * CodedOutputStream.computeTagSize(fieldNumber));
511 static int computeSizeUInt32ListNoTag(List<Integer> list) {
512 final int length = list.size();
519 if (list instanceof IntArrayList) {
520 final IntArrayList primitiveList = (IntArrayList) list;
522 size += CodedOutputStream.computeUInt32SizeNoTag(primitiveList.getInt(
i));
526 size += CodedOutputStream.computeUInt32SizeNoTag(list.get(
i));
532 static int computeSizeUInt32List(
int fieldNumber, List<Integer> list,
boolean packed) {
533 final int length = list.size();
537 int size = computeSizeUInt32ListNoTag(list);
540 return CodedOutputStream.computeTagSize(fieldNumber)
541 + CodedOutputStream.computeLengthDelimitedFieldSize(
size);
543 return size + (
length * CodedOutputStream.computeTagSize(fieldNumber));
547 static int computeSizeSInt32ListNoTag(List<Integer> list) {
548 final int length = list.size();
555 if (list instanceof IntArrayList) {
556 final IntArrayList primitiveList = (IntArrayList) list;
558 size += CodedOutputStream.computeSInt32SizeNoTag(primitiveList.getInt(
i));
562 size += CodedOutputStream.computeSInt32SizeNoTag(list.get(
i));
568 static int computeSizeSInt32List(
int fieldNumber, List<Integer> list,
boolean packed) {
569 final int length = list.size();
574 int size = computeSizeSInt32ListNoTag(list);
577 return CodedOutputStream.computeTagSize(fieldNumber)
578 + CodedOutputStream.computeLengthDelimitedFieldSize(
size);
580 return size + (
length * CodedOutputStream.computeTagSize(fieldNumber));
584 static int computeSizeFixed32ListNoTag(List<?> list) {
585 return list.size() * WireFormat.FIXED32_SIZE;
588 static int computeSizeFixed32List(
int fieldNumber, List<?> list,
boolean packed) {
589 final int length = list.size();
594 int dataSize =
length * WireFormat.FIXED32_SIZE;
595 return CodedOutputStream.computeTagSize(fieldNumber)
596 + CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
598 return length * CodedOutputStream.computeFixed32Size(fieldNumber, 0);
602 static int computeSizeFixed64ListNoTag(List<?> list) {
603 return list.size() * WireFormat.FIXED64_SIZE;
606 static int computeSizeFixed64List(
int fieldNumber, List<?> list,
boolean packed) {
607 final int length = list.size();
612 final int dataSize =
length * WireFormat.FIXED64_SIZE;
613 return CodedOutputStream.computeTagSize(fieldNumber)
614 + CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
616 return length * CodedOutputStream.computeFixed64Size(fieldNumber, 0);
620 static int computeSizeBoolListNoTag(List<?> list) {
625 static int computeSizeBoolList(
int fieldNumber, List<?> list,
boolean packed) {
626 final int length = list.size();
632 return CodedOutputStream.computeTagSize(fieldNumber)
633 + CodedOutputStream.computeLengthDelimitedFieldSize(
length);
635 return length * CodedOutputStream.computeBoolSize(fieldNumber,
true);
639 static int computeSizeStringList(
int fieldNumber, List<?> list) {
640 final int length = list.size();
644 int size =
length * CodedOutputStream.computeTagSize(fieldNumber);
645 if (list instanceof LazyStringList) {
646 LazyStringList lazyList = ((LazyStringList) list);
648 Object
value = lazyList.getRaw(
i);
649 if (
value instanceof ByteString) {
650 size += CodedOutputStream.computeBytesSizeNoTag((ByteString)
value);
652 size += CodedOutputStream.computeStringSizeNoTag((String)
value);
657 Object
value = list.get(
i);
658 if (
value instanceof ByteString) {
659 size += CodedOutputStream.computeBytesSizeNoTag((ByteString)
value);
661 size += CodedOutputStream.computeStringSizeNoTag((String)
value);
668 static int computeSizeMessage(
int fieldNumber, Object
value, Schema schema) {
669 if (
value instanceof LazyFieldLite) {
670 return CodedOutputStream.computeLazyFieldSize(fieldNumber, (LazyFieldLite)
value);
672 return CodedOutputStream.computeMessageSize(fieldNumber, (MessageLite)
value, schema);
676 static int computeSizeMessageList(
int fieldNumber, List<?> list) {
677 final int length = list.size();
681 int size =
length * CodedOutputStream.computeTagSize(fieldNumber);
683 Object
value = list.get(
i);
684 if (
value instanceof LazyFieldLite) {
685 size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite)
value);
687 size += CodedOutputStream.computeMessageSizeNoTag((MessageLite)
value);
693 static int computeSizeMessageList(
int fieldNumber, List<?> list, Schema schema) {
694 final int length = list.size();
698 int size =
length * CodedOutputStream.computeTagSize(fieldNumber);
700 Object
value = list.get(
i);
701 if (
value instanceof LazyFieldLite) {
702 size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite)
value);
704 size += CodedOutputStream.computeMessageSizeNoTag((MessageLite)
value, schema);
710 static int computeSizeByteStringList(
int fieldNumber, List<ByteString> list) {
711 final int length = list.size();
715 int size =
length * CodedOutputStream.computeTagSize(fieldNumber);
716 for (
int i = 0;
i < list.size();
i++) {
717 size += CodedOutputStream.computeBytesSizeNoTag(list.get(
i));
722 static int computeSizeGroupList(
int fieldNumber, List<MessageLite> list) {
723 final int length = list.size();
729 size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(
i));
734 static int computeSizeGroupList(
int fieldNumber, List<MessageLite> list, Schema schema) {
735 final int length = list.size();
741 size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(
i), schema);
751 public static boolean shouldUseTableSwitch(FieldInfo[]
fields) {
758 int lo =
fields[0].getFieldNumber();
760 return shouldUseTableSwitch(lo, hi,
fields.length);
774 public static boolean shouldUseTableSwitch(
int lo,
int hi,
int numFields) {
775 if (hi < DEFAULT_LOOK_UP_START_NUMBER) {
778 long tableSpaceCost = ((
long) hi - lo + 1);
779 long tableTimeCost = 3;
780 long lookupSpaceCost = 3 + 2 * (
long) numFields;
781 long lookupTimeCost = 3 + (
long) numFields;
782 return tableSpaceCost + 3 * tableTimeCost <= lookupSpaceCost + 3 * lookupTimeCost;
785 public static UnknownFieldSchema<?, ?> proto2UnknownFieldSetSchema() {
786 return PROTO2_UNKNOWN_FIELD_SET_SCHEMA;
789 public static UnknownFieldSchema<?, ?> proto3UnknownFieldSetSchema() {
790 return PROTO3_UNKNOWN_FIELD_SET_SCHEMA;
793 public static UnknownFieldSchema<?, ?> unknownFieldSetLiteSchema() {
794 return UNKNOWN_FIELD_SET_LITE_SCHEMA;
797 private static UnknownFieldSchema<?, ?> getUnknownFieldSetSchema(
boolean proto3) {
799 Class<?> clz = getUnknownFieldSetSchemaClass();
803 return (UnknownFieldSchema) clz.getConstructor(
boolean.
class).newInstance(proto3);
804 }
catch (Throwable t) {
809 private static Class<?> getGeneratedMessageClass() {
811 return Class.forName(
"com.google.protobuf.GeneratedMessageV3");
812 }
catch (Throwable e) {
817 private static Class<?> getUnknownFieldSetSchemaClass() {
819 return Class.forName(
"com.google.protobuf.UnknownFieldSetSchema");
820 }
catch (Throwable e) {
825 static Object getMapDefaultEntry(Class<?> clazz, String
name) {
828 Class.forName(clazz.getName() +
"$" + toCamelCase(
name,
true) +
"DefaultEntryHolder");
831 throw new IllegalStateException(
832 "Unable to look up map field default entry holder class for "
837 return UnsafeUtil.getStaticObject(
fields[0]);
838 }
catch (Throwable t) {
839 throw new RuntimeException(t);
843 static String toCamelCase(String
name,
boolean capNext) {
844 StringBuilder
sb =
new StringBuilder();
845 for (
int i = 0;
i <
name.length(); ++
i) {
846 char c =
name.charAt(
i);
848 if (
'a' <= c && c <=
'z') {
850 sb.append((
char) (c + (
'A' -
'a')));
855 }
else if (
'A' <= c && c <=
'Z') {
856 if (
i == 0 && !capNext) {
858 sb.append((
char) (c - (
'A' -
'a')));
863 }
else if (
'0' <= c && c <=
'9') {
870 return sb.toString();
874 static boolean safeEquals(Object
a, Object
b) {
875 return a ==
b || (
a !=
null &&
a.equals(
b));
878 static <T>
void mergeMap(MapFieldSchema mapFieldSchema,
T message,
T o,
long offset) {
880 mapFieldSchema.mergeFrom(
885 static <T, FT extends FieldDescriptorLite<FT>>
void mergeExtensions(
886 ExtensionSchema<FT> schema,
T message,
T other) {
887 FieldSet<FT> otherExtensions = schema.getExtensions(other);
888 if (!otherExtensions.isEmpty()) {
889 FieldSet<FT> messageExtensions = schema.getMutableExtensions(
message);
890 messageExtensions.mergeFrom(otherExtensions);
894 static <T, UT, UB>
void mergeUnknownFields(
895 UnknownFieldSchema<UT, UB> schema,
T message,
T other) {
896 UT messageUnknowns = schema.getFromMessage(
message);
897 UT otherUnknowns = schema.getFromMessage(other);
898 UT
merged = schema.merge(messageUnknowns, otherUnknowns);
903 static <UT, UB> UB filterUnknownEnumList(
905 List<Integer> enumList,
906 EnumLiteMap<?> enumMap,
908 UnknownFieldSchema<UT, UB> unknownFieldSchema) {
909 if (enumMap ==
null) {
910 return unknownFields;
913 if (enumList instanceof RandomAccess) {
915 int size = enumList.size();
916 for (
int readPos = 0; readPos <
size; ++readPos) {
917 int enumValue = enumList.get(readPos);
918 if (enumMap.findValueByNumber(enumValue) !=
null) {
919 if (readPos != writePos) {
920 enumList.set(writePos, enumValue);
924 unknownFields = storeUnknownEnum(
number, enumValue, unknownFields, unknownFieldSchema);
927 if (writePos !=
size) {
928 enumList.subList(writePos,
size).clear();
931 for (Iterator<Integer>
it = enumList.iterator();
it.hasNext(); ) {
932 int enumValue =
it.next();
933 if (enumMap.findValueByNumber(enumValue) ==
null) {
934 unknownFields = storeUnknownEnum(
number, enumValue, unknownFields, unknownFieldSchema);
939 return unknownFields;
943 static <UT, UB> UB filterUnknownEnumList(
945 List<Integer> enumList,
946 EnumVerifier enumVerifier,
948 UnknownFieldSchema<UT, UB> unknownFieldSchema) {
949 if (enumVerifier ==
null) {
950 return unknownFields;
953 if (enumList instanceof RandomAccess) {
955 int size = enumList.size();
956 for (
int readPos = 0; readPos <
size; ++readPos) {
957 int enumValue = enumList.get(readPos);
958 if (enumVerifier.isInRange(enumValue)) {
959 if (readPos != writePos) {
960 enumList.set(writePos, enumValue);
964 unknownFields = storeUnknownEnum(
number, enumValue, unknownFields, unknownFieldSchema);
967 if (writePos !=
size) {
968 enumList.subList(writePos,
size).clear();
971 for (Iterator<Integer>
it = enumList.iterator();
it.hasNext(); ) {
972 int enumValue =
it.next();
973 if (!enumVerifier.isInRange(enumValue)) {
974 unknownFields = storeUnknownEnum(
number, enumValue, unknownFields, unknownFieldSchema);
979 return unknownFields;
983 static <UT, UB> UB storeUnknownEnum(
984 int number,
int enumValue, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
985 if (unknownFields ==
null) {
986 unknownFields = unknownFieldSchema.newBuilder();
988 unknownFieldSchema.addVarint(unknownFields,
number, enumValue);
989 return unknownFields;