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