| OLD | NEW |
| (Empty) | |
| 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 /** |
| 36 * {@code UnknownFieldSetLite} is used to keep track of fields which were seen |
| 37 * when parsing a protocol message but whose field numbers or types are |
| 38 * unrecognized. This most frequently occurs when new fields are added to a |
| 39 * message type and then messages containing those fields are read by old |
| 40 * software that was compiled before the new types were added. |
| 41 * |
| 42 * <p>For use by generated code only. |
| 43 * |
| 44 * @author dweis@google.com (Daniel Weis) |
| 45 */ |
| 46 public final class UnknownFieldSetLite { |
| 47 |
| 48 private static final UnknownFieldSetLite DEFAULT_INSTANCE = |
| 49 new UnknownFieldSetLite(ByteString.EMPTY); |
| 50 |
| 51 /** |
| 52 * Get an empty {@code UnknownFieldSetLite}. |
| 53 * |
| 54 * <p>For use by generated code only. |
| 55 */ |
| 56 public static UnknownFieldSetLite getDefaultInstance() { |
| 57 return DEFAULT_INSTANCE; |
| 58 } |
| 59 |
| 60 /** |
| 61 * Create a new {@link Builder}. |
| 62 * |
| 63 * <p>For use by generated code only. |
| 64 */ |
| 65 public static Builder newBuilder() { |
| 66 return new Builder(); |
| 67 } |
| 68 |
| 69 /** |
| 70 * Returns an {@code UnknownFieldSetLite} that is the composite of {@code firs
t} and |
| 71 * {@code second}. |
| 72 */ |
| 73 static UnknownFieldSetLite concat(UnknownFieldSetLite first, UnknownFieldSetLi
te second) { |
| 74 return new UnknownFieldSetLite(first.byteString.concat(second.byteString)); |
| 75 } |
| 76 |
| 77 /** |
| 78 * The internal representation of the unknown fields. |
| 79 */ |
| 80 private final ByteString byteString; |
| 81 |
| 82 /** |
| 83 * Constructs the {@code UnknownFieldSetLite} as a thin wrapper around {@link
ByteString}. |
| 84 */ |
| 85 private UnknownFieldSetLite(ByteString byteString) { |
| 86 this.byteString = byteString; |
| 87 } |
| 88 |
| 89 /** |
| 90 * Serializes the set and writes it to {@code output}. |
| 91 * |
| 92 * <p>For use by generated code only. |
| 93 */ |
| 94 public void writeTo(CodedOutputStream output) throws IOException { |
| 95 output.writeRawBytes(byteString); |
| 96 } |
| 97 |
| 98 |
| 99 /** |
| 100 * Get the number of bytes required to encode this set. |
| 101 * |
| 102 * <p>For use by generated code only. |
| 103 */ |
| 104 public int getSerializedSize() { |
| 105 return byteString.size(); |
| 106 } |
| 107 |
| 108 @Override |
| 109 public boolean equals(Object obj) { |
| 110 if (this == obj) { |
| 111 return true; |
| 112 } |
| 113 |
| 114 if (obj instanceof UnknownFieldSetLite) { |
| 115 return byteString.equals(((UnknownFieldSetLite) obj).byteString); |
| 116 } |
| 117 |
| 118 return false; |
| 119 } |
| 120 |
| 121 @Override |
| 122 public int hashCode() { |
| 123 return byteString.hashCode(); |
| 124 } |
| 125 |
| 126 /** |
| 127 * Builder for {@link UnknownFieldSetLite}s. |
| 128 * |
| 129 * <p>Use {@link UnknownFieldSet#newBuilder()} to construct a {@code Builder}. |
| 130 * |
| 131 * <p>For use by generated code only. |
| 132 */ |
| 133 public static final class Builder { |
| 134 |
| 135 private ByteString.Output byteStringOutput; |
| 136 private CodedOutputStream output; |
| 137 private boolean built; |
| 138 |
| 139 /** |
| 140 * Constructs a {@code Builder}. Lazily initialized by |
| 141 * {@link #ensureInitializedButNotBuilt()}. |
| 142 */ |
| 143 private Builder() {} |
| 144 |
| 145 /** |
| 146 * Ensures internal state is initialized for use. |
| 147 */ |
| 148 private void ensureInitializedButNotBuilt() { |
| 149 if (built) { |
| 150 throw new IllegalStateException("Do not reuse UnknownFieldSetLite Builde
rs."); |
| 151 } |
| 152 |
| 153 if (output == null && byteStringOutput == null) { |
| 154 byteStringOutput = ByteString.newOutput(100 /* initialCapacity */); |
| 155 output = CodedOutputStream.newInstance(byteStringOutput); |
| 156 } |
| 157 } |
| 158 |
| 159 /** |
| 160 * Parse a single field from {@code input} and merge it into this set. |
| 161 * |
| 162 * <p>For use by generated code only. |
| 163 * |
| 164 * @param tag The field's tag number, which was already parsed. |
| 165 * @return {@code false} if the tag is an end group tag. |
| 166 */ |
| 167 public boolean mergeFieldFrom(final int tag, final CodedInputStream input) |
| 168 throws IOException { |
| 169 ensureInitializedButNotBuilt(); |
| 170 |
| 171 final int fieldNumber = WireFormat.getTagFieldNumber(tag); |
| 172 switch (WireFormat.getTagWireType(tag)) { |
| 173 case WireFormat.WIRETYPE_VARINT: |
| 174 output.writeUInt64(fieldNumber, input.readInt64()); |
| 175 return true; |
| 176 case WireFormat.WIRETYPE_FIXED32: |
| 177 output.writeFixed32(fieldNumber, input.readFixed32()); |
| 178 return true; |
| 179 case WireFormat.WIRETYPE_FIXED64: |
| 180 output.writeFixed64(fieldNumber, input.readFixed64()); |
| 181 return true; |
| 182 case WireFormat.WIRETYPE_LENGTH_DELIMITED: |
| 183 output.writeBytes(fieldNumber, input.readBytes()); |
| 184 return true; |
| 185 case WireFormat.WIRETYPE_START_GROUP: |
| 186 final Builder subBuilder = newBuilder(); |
| 187 subBuilder.mergeFrom(input); |
| 188 input.checkLastTagWas( |
| 189 WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); |
| 190 |
| 191 output.writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP); |
| 192 subBuilder.build().writeTo(output); |
| 193 output.writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP); |
| 194 return true; |
| 195 case WireFormat.WIRETYPE_END_GROUP: |
| 196 return false; |
| 197 default: |
| 198 throw InvalidProtocolBufferException.invalidWireType(); |
| 199 } |
| 200 } |
| 201 |
| 202 /** |
| 203 * Convenience method for merging a new field containing a single varint |
| 204 * value. This is used in particular when an unknown enum value is |
| 205 * encountered. |
| 206 * |
| 207 * <p>For use by generated code only. |
| 208 */ |
| 209 public Builder mergeVarintField(int fieldNumber, int value) { |
| 210 if (fieldNumber == 0) { |
| 211 throw new IllegalArgumentException("Zero is not a valid field number."); |
| 212 } |
| 213 ensureInitializedButNotBuilt(); |
| 214 try { |
| 215 output.writeUInt64(fieldNumber, value); |
| 216 } catch (IOException e) { |
| 217 // Should never happen. |
| 218 } |
| 219 return this; |
| 220 } |
| 221 |
| 222 /** |
| 223 * Convenience method for merging a length-delimited field. |
| 224 * |
| 225 * <p>For use by generated code only. |
| 226 */ |
| 227 public Builder mergeLengthDelimitedField( |
| 228 final int fieldNumber, final ByteString value) { |
| 229 if (fieldNumber == 0) { |
| 230 throw new IllegalArgumentException("Zero is not a valid field number."); |
| 231 } |
| 232 ensureInitializedButNotBuilt(); |
| 233 try { |
| 234 output.writeBytes(fieldNumber, value); |
| 235 } catch (IOException e) { |
| 236 // Should never happen. |
| 237 } |
| 238 return this; |
| 239 } |
| 240 |
| 241 /** |
| 242 * Build the {@link UnknownFieldSetLite} and return it. |
| 243 * |
| 244 * <p>Once {@code build()} has been called, the {@code Builder} will no |
| 245 * longer be usable. Calling any method after {@code build()} will result |
| 246 * in undefined behavior and can cause a {@code IllegalStateException} to be |
| 247 * thrown. |
| 248 * |
| 249 * <p>For use by generated code only. |
| 250 */ |
| 251 public UnknownFieldSetLite build() { |
| 252 if (built) { |
| 253 throw new IllegalStateException("Do not reuse UnknownFieldSetLite Builde
rs."); |
| 254 } |
| 255 |
| 256 built = true; |
| 257 |
| 258 final UnknownFieldSetLite result; |
| 259 // If we were never initialized, no data was written. |
| 260 if (output == null) { |
| 261 result = getDefaultInstance(); |
| 262 } else { |
| 263 try { |
| 264 output.flush(); |
| 265 } catch (IOException e) { |
| 266 // Should never happen. |
| 267 } |
| 268 ByteString byteString = byteStringOutput.toByteString(); |
| 269 if (byteString.isEmpty()) { |
| 270 result = getDefaultInstance(); |
| 271 } else { |
| 272 result = new UnknownFieldSetLite(byteString); |
| 273 } |
| 274 } |
| 275 |
| 276 // Allow for garbage collection. |
| 277 output = null; |
| 278 byteStringOutput = null; |
| 279 return result; |
| 280 } |
| 281 |
| 282 /** |
| 283 * Parse an entire message from {@code input} and merge its fields into |
| 284 * this set. |
| 285 */ |
| 286 private Builder mergeFrom(final CodedInputStream input) throws IOException { |
| 287 // Ensures initialization in mergeFieldFrom. |
| 288 while (true) { |
| 289 final int tag = input.readTag(); |
| 290 if (tag == 0 || !mergeFieldFrom(tag, input)) { |
| 291 break; |
| 292 } |
| 293 } |
| 294 return this; |
| 295 } |
| 296 } |
| 297 } |
| OLD | NEW |