1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import java.io.IOException; 34 35 @ExperimentalApi 36 abstract class UnknownFieldSchema<T, B> { 37 38 /** Whether unknown fields should be dropped. */ shouldDiscardUnknownFields(Reader reader)39 abstract boolean shouldDiscardUnknownFields(Reader reader); 40 41 /** Adds a varint value to the unknown fields. */ addVarint(B fields, int number, long value)42 abstract void addVarint(B fields, int number, long value); 43 44 /** Adds a fixed32 value to the unknown fields. */ addFixed32(B fields, int number, int value)45 abstract void addFixed32(B fields, int number, int value); 46 47 /** Adds a fixed64 value to the unknown fields. */ addFixed64(B fields, int number, long value)48 abstract void addFixed64(B fields, int number, long value); 49 50 /** Adds a length delimited value to the unknown fields. */ addLengthDelimited(B fields, int number, ByteString value)51 abstract void addLengthDelimited(B fields, int number, ByteString value); 52 53 /** Adds a group value to the unknown fields. */ addGroup(B fields, int number, T subFieldSet)54 abstract void addGroup(B fields, int number, T subFieldSet); 55 56 /** Create a new builder for unknown fields. */ newBuilder()57 abstract B newBuilder(); 58 59 /** Returns an immutable instance of the field container. */ toImmutable(B fields)60 abstract T toImmutable(B fields); 61 62 /** 63 * Sets the unknown fields into the message. Caller must take care of the mutability of the 64 * fields. 65 */ setToMessage(Object message, T fields)66 abstract void setToMessage(Object message, T fields); 67 68 /** Get the unknown fields from the message. */ getFromMessage(Object message)69 abstract T getFromMessage(Object message); 70 71 /** Returns a builder for unknown fields in the message. */ getBuilderFromMessage(Object message)72 abstract B getBuilderFromMessage(Object message); 73 74 /** Sets an unknown field builder into the message. */ setBuilderToMessage(Object message, B builder)75 abstract void setBuilderToMessage(Object message, B builder); 76 77 /** Marks unknown fields as immutable. */ makeImmutable(Object message)78 abstract void makeImmutable(Object message); 79 80 /** Merges one field into the unknown fields. */ mergeOneFieldFrom(B unknownFields, Reader reader)81 final boolean mergeOneFieldFrom(B unknownFields, Reader reader) throws IOException { 82 int tag = reader.getTag(); 83 int fieldNumber = WireFormat.getTagFieldNumber(tag); 84 switch (WireFormat.getTagWireType(tag)) { 85 case WireFormat.WIRETYPE_VARINT: 86 addVarint(unknownFields, fieldNumber, reader.readInt64()); 87 return true; 88 case WireFormat.WIRETYPE_FIXED32: 89 addFixed32(unknownFields, fieldNumber, reader.readFixed32()); 90 return true; 91 case WireFormat.WIRETYPE_FIXED64: 92 addFixed64(unknownFields, fieldNumber, reader.readFixed64()); 93 return true; 94 case WireFormat.WIRETYPE_LENGTH_DELIMITED: 95 addLengthDelimited(unknownFields, fieldNumber, reader.readBytes()); 96 return true; 97 case WireFormat.WIRETYPE_START_GROUP: 98 final B subFields = newBuilder(); 99 int endGroupTag = WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP); 100 mergeFrom(subFields, reader); 101 if (endGroupTag != reader.getTag()) { 102 throw InvalidProtocolBufferException.invalidEndTag(); 103 } 104 addGroup(unknownFields, fieldNumber, toImmutable(subFields)); 105 return true; 106 case WireFormat.WIRETYPE_END_GROUP: 107 return false; 108 default: 109 throw InvalidProtocolBufferException.invalidWireType(); 110 } 111 } 112 mergeFrom(B unknownFields, Reader reader)113 final void mergeFrom(B unknownFields, Reader reader) throws IOException { 114 while (true) { 115 if (reader.getFieldNumber() == Reader.READ_DONE 116 || !mergeOneFieldFrom(unknownFields, reader)) { 117 break; 118 } 119 } 120 } 121 writeTo(T unknownFields, Writer writer)122 abstract void writeTo(T unknownFields, Writer writer) throws IOException; 123 writeAsMessageSetTo(T unknownFields, Writer writer)124 abstract void writeAsMessageSetTo(T unknownFields, Writer writer) throws IOException; 125 126 /** Merges {@code source} into {@code destination} and returns the merged instance. */ merge(T destination, T source)127 abstract T merge(T destination, T source); 128 129 /** Get the serialized size for message set serialization. */ getSerializedSizeAsMessageSet(T message)130 abstract int getSerializedSizeAsMessageSet(T message); 131 getSerializedSize(T unknowns)132 abstract int getSerializedSize(T unknowns); 133 } 134