com.google.protobuf.ExtensionSchemaLite Maven / Gradle / Ivy
The newest version!
// 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.GeneratedMessageLite.ExtensionDescriptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@CheckReturnValue
@SuppressWarnings("unchecked")
final class ExtensionSchemaLite extends ExtensionSchema {
@Override
boolean hasExtensions(MessageLite prototype) {
return prototype instanceof GeneratedMessageLite.ExtendableMessage;
}
@Override
FieldSet getExtensions(Object message) {
return ((GeneratedMessageLite.ExtendableMessage, ?>) message).extensions;
}
@Override
void setExtensions(Object message, FieldSet extensions) {
((GeneratedMessageLite.ExtendableMessage, ?>) message).extensions = extensions;
}
@Override
FieldSet getMutableExtensions(Object message) {
return ((GeneratedMessageLite.ExtendableMessage, ?>) message).ensureExtensionsAreMutable();
}
@Override
void makeImmutable(Object message) {
getExtensions(message).makeImmutable();
}
@Override
UB parseExtension(
Object containerMessage,
Reader reader,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
FieldSet extensions,
UB unknownFields,
UnknownFieldSchema unknownFieldSchema)
throws IOException {
GeneratedMessageLite.GeneratedExtension, ?> extension =
(GeneratedMessageLite.GeneratedExtension, ?>) extensionObject;
int fieldNumber = extension.getNumber();
if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) {
Object value = null;
switch (extension.getLiteType()) {
case DOUBLE:
{
List list = new ArrayList();
reader.readDoubleList(list);
value = list;
break;
}
case FLOAT:
{
List list = new ArrayList();
reader.readFloatList(list);
value = list;
break;
}
case INT64:
{
List list = new ArrayList();
reader.readInt64List(list);
value = list;
break;
}
case UINT64:
{
List list = new ArrayList();
reader.readUInt64List(list);
value = list;
break;
}
case INT32:
{
List list = new ArrayList();
reader.readInt32List(list);
value = list;
break;
}
case FIXED64:
{
List list = new ArrayList();
reader.readFixed64List(list);
value = list;
break;
}
case FIXED32:
{
List list = new ArrayList();
reader.readFixed32List(list);
value = list;
break;
}
case BOOL:
{
List list = new ArrayList();
reader.readBoolList(list);
value = list;
break;
}
case UINT32:
{
List list = new ArrayList();
reader.readUInt32List(list);
value = list;
break;
}
case SFIXED32:
{
List list = new ArrayList();
reader.readSFixed32List(list);
value = list;
break;
}
case SFIXED64:
{
List list = new ArrayList();
reader.readSFixed64List(list);
value = list;
break;
}
case SINT32:
{
List list = new ArrayList();
reader.readSInt32List(list);
value = list;
break;
}
case SINT64:
{
List list = new ArrayList();
reader.readSInt64List(list);
value = list;
break;
}
case ENUM:
{
List list = new ArrayList();
reader.readEnumList(list);
unknownFields =
SchemaUtil.filterUnknownEnumList(
containerMessage,
fieldNumber,
list,
extension.descriptor.getEnumType(),
unknownFields,
unknownFieldSchema);
value = list;
break;
}
default:
throw new IllegalStateException(
"Type cannot be packed: " + extension.descriptor.getLiteType());
}
extensions.setField(extension.descriptor, value);
} else {
Object value = null;
// Enum is a special case because unknown enum values will be put into UnknownFieldSetLite.
if (extension.getLiteType() == WireFormat.FieldType.ENUM) {
int number = reader.readInt32();
Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number);
if (enumValue == null) {
return SchemaUtil.storeUnknownEnum(
containerMessage, fieldNumber, number, unknownFields, unknownFieldSchema);
}
// Note, we store the integer value instead of the actual enum object in FieldSet.
// This is also different from full-runtime where we store EnumValueDescriptor.
value = number;
} else {
switch (extension.getLiteType()) {
case DOUBLE:
value = reader.readDouble();
break;
case FLOAT:
value = reader.readFloat();
break;
case INT64:
value = reader.readInt64();
break;
case UINT64:
value = reader.readUInt64();
break;
case INT32:
value = reader.readInt32();
break;
case FIXED64:
value = reader.readFixed64();
break;
case FIXED32:
value = reader.readFixed32();
break;
case BOOL:
value = reader.readBool();
break;
case BYTES:
value = reader.readBytes();
break;
case UINT32:
value = reader.readUInt32();
break;
case SFIXED32:
value = reader.readSFixed32();
break;
case SFIXED64:
value = reader.readSFixed64();
break;
case SINT32:
value = reader.readSInt32();
break;
case SINT64:
value = reader.readSInt64();
break;
case STRING:
value = reader.readString();
break;
case GROUP:
// Special case handling for non-repeated sub-messages: merge in-place rather than
// building up new sub-messages and merging those, which is too slow.
// TODO(b/249368670): clean this up
if (!extension.isRepeated()) {
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue instanceof GeneratedMessageLite) {
Schema extSchema = Protobuf.getInstance().schemaFor(oldValue);
if (!((GeneratedMessageLite, ?>) oldValue).isMutable()) {
Object newValue = extSchema.newInstance();
extSchema.mergeFrom(newValue, oldValue);
extensions.setField(extension.descriptor, newValue);
oldValue = newValue;
}
reader.mergeGroupField(oldValue, extSchema, extensionRegistry);
return unknownFields;
}
}
value =
reader.readGroup(
extension.getMessageDefaultInstance().getClass(), extensionRegistry);
break;
case MESSAGE:
// Special case handling for non-repeated sub-messages: merge in-place rather than
// building up new sub-messages and merging those, which is too slow.
// TODO(b/249368670): clean this up
if (!extension.isRepeated()) {
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue instanceof GeneratedMessageLite) {
Schema extSchema = Protobuf.getInstance().schemaFor(oldValue);
if (!((GeneratedMessageLite, ?>) oldValue).isMutable()) {
Object newValue = extSchema.newInstance();
extSchema.mergeFrom(newValue, oldValue);
extensions.setField(extension.descriptor, newValue);
oldValue = newValue;
}
reader.mergeMessageField(oldValue, extSchema, extensionRegistry);
return unknownFields;
}
}
value =
reader.readMessage(
extension.getMessageDefaultInstance().getClass(), extensionRegistry);
break;
case ENUM:
throw new IllegalStateException("Shouldn't reach here.");
}
}
if (extension.isRepeated()) {
extensions.addRepeatedField(extension.descriptor, value);
} else {
switch (extension.getLiteType()) {
case MESSAGE:
case GROUP:
// TODO(b/249368670): this shouldn't be reachable, clean this up
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue != null) {
value = Internal.mergeMessage(oldValue, value);
}
break;
default:
break;
}
extensions.setField(extension.descriptor, value);
}
}
return unknownFields;
}
@Override
int extensionNumber(Map.Entry, ?> extension) {
GeneratedMessageLite.ExtensionDescriptor descriptor =
(GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
return descriptor.getNumber();
}
@Override
void serializeExtension(Writer writer, Map.Entry, ?> extension) throws IOException {
GeneratedMessageLite.ExtensionDescriptor descriptor =
(GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
if (descriptor.isRepeated()) {
switch (descriptor.getLiteType()) {
case DOUBLE:
SchemaUtil.writeDoubleList(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FLOAT:
SchemaUtil.writeFloatList(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case INT64:
SchemaUtil.writeInt64List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case UINT64:
SchemaUtil.writeUInt64List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case INT32:
SchemaUtil.writeInt32List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FIXED64:
SchemaUtil.writeFixed64List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FIXED32:
SchemaUtil.writeFixed32List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case BOOL:
SchemaUtil.writeBoolList(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case BYTES:
SchemaUtil.writeBytesList(
descriptor.getNumber(), (List) extension.getValue(), writer);
break;
case UINT32:
SchemaUtil.writeUInt32List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SFIXED32:
SchemaUtil.writeSFixed32List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SFIXED64:
SchemaUtil.writeSFixed64List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SINT32:
SchemaUtil.writeSInt32List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SINT64:
SchemaUtil.writeSInt64List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case ENUM:
SchemaUtil.writeInt32List(
descriptor.getNumber(),
(List) extension.getValue(),
writer,
descriptor.isPacked());
break;
case STRING:
SchemaUtil.writeStringList(
descriptor.getNumber(), (List) extension.getValue(), writer);
break;
case GROUP:
{
List> data = (List>) extension.getValue();
if (data != null && !data.isEmpty()) {
SchemaUtil.writeGroupList(
descriptor.getNumber(),
(List>) extension.getValue(),
writer,
Protobuf.getInstance().schemaFor(data.get(0).getClass()));
}
}
break;
case MESSAGE:
{
List> data = (List>) extension.getValue();
if (data != null && !data.isEmpty()) {
SchemaUtil.writeMessageList(
descriptor.getNumber(),
(List>) extension.getValue(),
writer,
Protobuf.getInstance().schemaFor(data.get(0).getClass()));
}
}
break;
}
} else {
switch (descriptor.getLiteType()) {
case DOUBLE:
writer.writeDouble(descriptor.getNumber(), (Double) extension.getValue());
break;
case FLOAT:
writer.writeFloat(descriptor.getNumber(), (Float) extension.getValue());
break;
case INT64:
writer.writeInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case UINT64:
writer.writeUInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case INT32:
writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case FIXED64:
writer.writeFixed64(descriptor.getNumber(), (Long) extension.getValue());
break;
case FIXED32:
writer.writeFixed32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case BOOL:
writer.writeBool(descriptor.getNumber(), (Boolean) extension.getValue());
break;
case BYTES:
writer.writeBytes(descriptor.getNumber(), (ByteString) extension.getValue());
break;
case UINT32:
writer.writeUInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SFIXED32:
writer.writeSFixed32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SFIXED64:
writer.writeSFixed64(descriptor.getNumber(), (Long) extension.getValue());
break;
case SINT32:
writer.writeSInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SINT64:
writer.writeSInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case ENUM:
writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case STRING:
writer.writeString(descriptor.getNumber(), (String) extension.getValue());
break;
case GROUP:
writer.writeGroup(
descriptor.getNumber(),
extension.getValue(),
Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
break;
case MESSAGE:
writer.writeMessage(
descriptor.getNumber(),
extension.getValue(),
Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
break;
}
}
}
@Override
Object findExtensionByNumber(
ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number) {
return extensionRegistry.findLiteExtensionByNumber(defaultInstance, number);
}
@Override
void parseLengthPrefixedMessageSetItem(
Reader reader,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
FieldSet extensions)
throws IOException {
GeneratedMessageLite.GeneratedExtension, ?> extension =
(GeneratedMessageLite.GeneratedExtension, ?>) extensionObject;
Object value =
reader.readMessage(extension.getMessageDefaultInstance().getClass(), extensionRegistry);
extensions.setField(extension.descriptor, value);
}
@Override
void parseMessageSetItem(
ByteString data,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
FieldSet extensions)
throws IOException {
GeneratedMessageLite.GeneratedExtension, ?> extension =
(GeneratedMessageLite.GeneratedExtension, ?>) extensionObject;
MessageLite.Builder builder = extension.getMessageDefaultInstance().newBuilderForType();
final CodedInputStream input = data.newCodedInput();
builder.mergeFrom(input, extensionRegistry);
extensions.setField(extension.descriptor, builder.buildPartial());
input.checkLastTagWas(0);
}
}