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 com.google.protobuf.Descriptors.EnumValueDescriptor; 34 import com.google.protobuf.Descriptors.FieldDescriptor; 35 import java.io.IOException; 36 import java.lang.reflect.Field; 37 import java.nio.ByteBuffer; 38 import java.util.ArrayList; 39 import java.util.List; 40 import java.util.Map; 41 42 @SuppressWarnings("unchecked") 43 final class ExtensionSchemaFull extends ExtensionSchema<FieldDescriptor> { 44 45 private static final long EXTENSION_FIELD_OFFSET = getExtensionsFieldOffset(); 46 getExtensionsFieldOffset()47 private static <T> long getExtensionsFieldOffset() { 48 try { 49 Field field = GeneratedMessageV3.ExtendableMessage.class.getDeclaredField("extensions"); 50 return UnsafeUtil.objectFieldOffset(field); 51 } catch (Throwable e) { 52 throw new IllegalStateException("Unable to lookup extension field offset"); 53 } 54 } 55 56 @Override hasExtensions(MessageLite prototype)57 boolean hasExtensions(MessageLite prototype) { 58 return prototype instanceof GeneratedMessageV3.ExtendableMessage; 59 } 60 61 @Override getExtensions(Object message)62 public FieldSet<FieldDescriptor> getExtensions(Object message) { 63 return (FieldSet<FieldDescriptor>) UnsafeUtil.getObject(message, EXTENSION_FIELD_OFFSET); 64 } 65 66 @Override setExtensions(Object message, FieldSet<FieldDescriptor> extensions)67 void setExtensions(Object message, FieldSet<FieldDescriptor> extensions) { 68 UnsafeUtil.putObject(message, EXTENSION_FIELD_OFFSET, extensions); 69 } 70 71 @Override getMutableExtensions(Object message)72 FieldSet<FieldDescriptor> getMutableExtensions(Object message) { 73 FieldSet<FieldDescriptor> extensions = getExtensions(message); 74 if (extensions.isImmutable()) { 75 extensions = extensions.clone(); 76 setExtensions(message, extensions); 77 } 78 return extensions; 79 } 80 81 @Override makeImmutable(Object message)82 void makeImmutable(Object message) { 83 getExtensions(message).makeImmutable(); 84 } 85 86 @Override parseExtension( Object containerMessage, Reader reader, Object extensionObject, ExtensionRegistryLite extensionRegistry, FieldSet<FieldDescriptor> extensions, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema)87 <UT, UB> UB parseExtension( 88 Object containerMessage, 89 Reader reader, 90 Object extensionObject, 91 ExtensionRegistryLite extensionRegistry, 92 FieldSet<FieldDescriptor> extensions, 93 UB unknownFields, 94 UnknownFieldSchema<UT, UB> unknownFieldSchema) 95 throws IOException { 96 ExtensionRegistry.ExtensionInfo extension = (ExtensionRegistry.ExtensionInfo) extensionObject; 97 int fieldNumber = extension.descriptor.getNumber(); 98 99 if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) { 100 Object value = null; 101 switch (extension.descriptor.getLiteType()) { 102 case DOUBLE: 103 { 104 List<Double> list = new ArrayList<Double>(); 105 reader.readDoubleList(list); 106 value = list; 107 break; 108 } 109 case FLOAT: 110 { 111 List<Float> list = new ArrayList<Float>(); 112 reader.readFloatList(list); 113 value = list; 114 break; 115 } 116 case INT64: 117 { 118 List<Long> list = new ArrayList<Long>(); 119 reader.readInt64List(list); 120 value = list; 121 break; 122 } 123 case UINT64: 124 { 125 List<Long> list = new ArrayList<Long>(); 126 reader.readUInt64List(list); 127 value = list; 128 break; 129 } 130 case INT32: 131 { 132 List<Integer> list = new ArrayList<Integer>(); 133 reader.readInt32List(list); 134 value = list; 135 break; 136 } 137 case FIXED64: 138 { 139 List<Long> list = new ArrayList<Long>(); 140 reader.readFixed64List(list); 141 value = list; 142 break; 143 } 144 case FIXED32: 145 { 146 List<Integer> list = new ArrayList<Integer>(); 147 reader.readFixed32List(list); 148 value = list; 149 break; 150 } 151 case BOOL: 152 { 153 List<Boolean> list = new ArrayList<Boolean>(); 154 reader.readBoolList(list); 155 value = list; 156 break; 157 } 158 case UINT32: 159 { 160 List<Integer> list = new ArrayList<Integer>(); 161 reader.readUInt32List(list); 162 value = list; 163 break; 164 } 165 case SFIXED32: 166 { 167 List<Integer> list = new ArrayList<Integer>(); 168 reader.readSFixed32List(list); 169 value = list; 170 break; 171 } 172 case SFIXED64: 173 { 174 List<Long> list = new ArrayList<Long>(); 175 reader.readSFixed64List(list); 176 value = list; 177 break; 178 } 179 case SINT32: 180 { 181 List<Integer> list = new ArrayList<Integer>(); 182 reader.readSInt32List(list); 183 value = list; 184 break; 185 } 186 case SINT64: 187 { 188 List<Long> list = new ArrayList<Long>(); 189 reader.readSInt64List(list); 190 value = list; 191 break; 192 } 193 case ENUM: 194 { 195 List<Integer> list = new ArrayList<Integer>(); 196 reader.readEnumList(list); 197 List<EnumValueDescriptor> enumList = new ArrayList<EnumValueDescriptor>(); 198 for (int number : list) { 199 EnumValueDescriptor enumDescriptor = 200 extension.descriptor.getEnumType().findValueByNumber(number); 201 if (enumDescriptor != null) { 202 enumList.add(enumDescriptor); 203 } else { 204 unknownFields = 205 SchemaUtil.storeUnknownEnum( 206 containerMessage, fieldNumber, number, unknownFields, unknownFieldSchema); 207 } 208 } 209 value = enumList; 210 break; 211 } 212 default: 213 throw new IllegalStateException( 214 "Type cannot be packed: " + extension.descriptor.getLiteType()); 215 } 216 extensions.setField(extension.descriptor, value); 217 } else { 218 Object value = null; 219 // Enum is a special case because unknown enum values will be put into UnknownFieldSetLite. 220 if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { 221 int number = reader.readInt32(); 222 Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number); 223 if (enumValue == null) { 224 return SchemaUtil.storeUnknownEnum( 225 containerMessage, fieldNumber, number, unknownFields, unknownFieldSchema); 226 } 227 value = enumValue; 228 } else { 229 switch (extension.descriptor.getLiteType()) { 230 case DOUBLE: 231 value = reader.readDouble(); 232 break; 233 case FLOAT: 234 value = reader.readFloat(); 235 break; 236 case INT64: 237 value = reader.readInt64(); 238 break; 239 case UINT64: 240 value = reader.readUInt64(); 241 break; 242 case INT32: 243 value = reader.readInt32(); 244 break; 245 case FIXED64: 246 value = reader.readFixed64(); 247 break; 248 case FIXED32: 249 value = reader.readFixed32(); 250 break; 251 case BOOL: 252 value = reader.readBool(); 253 break; 254 case BYTES: 255 value = reader.readBytes(); 256 break; 257 case UINT32: 258 value = reader.readUInt32(); 259 break; 260 case SFIXED32: 261 value = reader.readSFixed32(); 262 break; 263 case SFIXED64: 264 value = reader.readSFixed64(); 265 break; 266 case SINT32: 267 value = reader.readSInt32(); 268 break; 269 case SINT64: 270 value = reader.readSInt64(); 271 break; 272 273 case STRING: 274 value = reader.readString(); 275 break; 276 case GROUP: 277 value = reader.readGroup(extension.defaultInstance.getClass(), extensionRegistry); 278 break; 279 280 case MESSAGE: 281 value = reader.readMessage(extension.defaultInstance.getClass(), extensionRegistry); 282 break; 283 284 case ENUM: 285 throw new IllegalStateException("Shouldn't reach here."); 286 } 287 } 288 if (extension.descriptor.isRepeated()) { 289 extensions.addRepeatedField(extension.descriptor, value); 290 } else { 291 switch (extension.descriptor.getLiteType()) { 292 case MESSAGE: 293 case GROUP: 294 Object oldValue = extensions.getField(extension.descriptor); 295 if (oldValue != null) { 296 value = Internal.mergeMessage(oldValue, value); 297 } 298 break; 299 default: 300 break; 301 } 302 extensions.setField(extension.descriptor, value); 303 } 304 } 305 return unknownFields; 306 } 307 308 @Override extensionNumber(Map.Entry<?, ?> extension)309 int extensionNumber(Map.Entry<?, ?> extension) { 310 FieldDescriptor descriptor = (FieldDescriptor) extension.getKey(); 311 return descriptor.getNumber(); 312 } 313 314 @Override serializeExtension(Writer writer, Map.Entry<?, ?> extension)315 void serializeExtension(Writer writer, Map.Entry<?, ?> extension) throws IOException { 316 FieldDescriptor descriptor = (FieldDescriptor) extension.getKey(); 317 if (descriptor.isRepeated()) { 318 switch (descriptor.getLiteType()) { 319 case DOUBLE: 320 SchemaUtil.writeDoubleList( 321 descriptor.getNumber(), 322 (List<Double>) extension.getValue(), 323 writer, 324 descriptor.isPacked()); 325 break; 326 case FLOAT: 327 SchemaUtil.writeFloatList( 328 descriptor.getNumber(), 329 (List<Float>) extension.getValue(), 330 writer, 331 descriptor.isPacked()); 332 break; 333 case INT64: 334 SchemaUtil.writeInt64List( 335 descriptor.getNumber(), 336 (List<Long>) extension.getValue(), 337 writer, 338 descriptor.isPacked()); 339 break; 340 case UINT64: 341 SchemaUtil.writeUInt64List( 342 descriptor.getNumber(), 343 (List<Long>) extension.getValue(), 344 writer, 345 descriptor.isPacked()); 346 break; 347 case INT32: 348 SchemaUtil.writeInt32List( 349 descriptor.getNumber(), 350 (List<Integer>) extension.getValue(), 351 writer, 352 descriptor.isPacked()); 353 break; 354 case FIXED64: 355 SchemaUtil.writeFixed64List( 356 descriptor.getNumber(), 357 (List<Long>) extension.getValue(), 358 writer, 359 descriptor.isPacked()); 360 break; 361 case FIXED32: 362 SchemaUtil.writeFixed32List( 363 descriptor.getNumber(), 364 (List<Integer>) extension.getValue(), 365 writer, 366 descriptor.isPacked()); 367 break; 368 case BOOL: 369 SchemaUtil.writeBoolList( 370 descriptor.getNumber(), 371 (List<Boolean>) extension.getValue(), 372 writer, 373 descriptor.isPacked()); 374 break; 375 case BYTES: 376 SchemaUtil.writeBytesList( 377 descriptor.getNumber(), (List<ByteString>) extension.getValue(), writer); 378 break; 379 case UINT32: 380 SchemaUtil.writeUInt32List( 381 descriptor.getNumber(), 382 (List<Integer>) extension.getValue(), 383 writer, 384 descriptor.isPacked()); 385 break; 386 case SFIXED32: 387 SchemaUtil.writeSFixed32List( 388 descriptor.getNumber(), 389 (List<Integer>) extension.getValue(), 390 writer, 391 descriptor.isPacked()); 392 break; 393 case SFIXED64: 394 SchemaUtil.writeSFixed64List( 395 descriptor.getNumber(), 396 (List<Long>) extension.getValue(), 397 writer, 398 descriptor.isPacked()); 399 break; 400 case SINT32: 401 SchemaUtil.writeSInt32List( 402 descriptor.getNumber(), 403 (List<Integer>) extension.getValue(), 404 writer, 405 descriptor.isPacked()); 406 break; 407 case SINT64: 408 SchemaUtil.writeSInt64List( 409 descriptor.getNumber(), 410 (List<Long>) extension.getValue(), 411 writer, 412 descriptor.isPacked()); 413 break; 414 case ENUM: 415 { 416 List<EnumValueDescriptor> enumList = (List<EnumValueDescriptor>) extension.getValue(); 417 List<Integer> list = new ArrayList<Integer>(); 418 for (EnumValueDescriptor d : enumList) { 419 list.add(d.getNumber()); 420 } 421 SchemaUtil.writeInt32List(descriptor.getNumber(), list, writer, descriptor.isPacked()); 422 break; 423 } 424 case STRING: 425 SchemaUtil.writeStringList( 426 descriptor.getNumber(), (List<String>) extension.getValue(), writer); 427 break; 428 case GROUP: 429 SchemaUtil.writeGroupList(descriptor.getNumber(), (List<?>) extension.getValue(), writer); 430 break; 431 case MESSAGE: 432 SchemaUtil.writeMessageList( 433 descriptor.getNumber(), (List<?>) extension.getValue(), writer); 434 break; 435 } 436 } else { 437 switch (descriptor.getLiteType()) { 438 case DOUBLE: 439 writer.writeDouble(descriptor.getNumber(), (Double) extension.getValue()); 440 break; 441 case FLOAT: 442 writer.writeFloat(descriptor.getNumber(), (Float) extension.getValue()); 443 break; 444 case INT64: 445 writer.writeInt64(descriptor.getNumber(), (Long) extension.getValue()); 446 break; 447 case UINT64: 448 writer.writeUInt64(descriptor.getNumber(), (Long) extension.getValue()); 449 break; 450 case INT32: 451 writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue()); 452 break; 453 case FIXED64: 454 writer.writeFixed64(descriptor.getNumber(), (Long) extension.getValue()); 455 break; 456 case FIXED32: 457 writer.writeFixed32(descriptor.getNumber(), (Integer) extension.getValue()); 458 break; 459 case BOOL: 460 writer.writeBool(descriptor.getNumber(), (Boolean) extension.getValue()); 461 break; 462 case BYTES: 463 writer.writeBytes(descriptor.getNumber(), (ByteString) extension.getValue()); 464 break; 465 case UINT32: 466 writer.writeUInt32(descriptor.getNumber(), (Integer) extension.getValue()); 467 break; 468 case SFIXED32: 469 writer.writeSFixed32(descriptor.getNumber(), (Integer) extension.getValue()); 470 break; 471 case SFIXED64: 472 writer.writeSFixed64(descriptor.getNumber(), (Long) extension.getValue()); 473 break; 474 case SINT32: 475 writer.writeSInt32(descriptor.getNumber(), (Integer) extension.getValue()); 476 break; 477 case SINT64: 478 writer.writeSInt64(descriptor.getNumber(), (Long) extension.getValue()); 479 break; 480 case ENUM: 481 writer.writeInt32( 482 descriptor.getNumber(), ((EnumValueDescriptor) extension.getValue()).getNumber()); 483 break; 484 case STRING: 485 writer.writeString(descriptor.getNumber(), (String) extension.getValue()); 486 break; 487 case GROUP: 488 writer.writeGroup(descriptor.getNumber(), extension.getValue()); 489 break; 490 case MESSAGE: 491 writer.writeMessage(descriptor.getNumber(), extension.getValue()); 492 break; 493 } 494 } 495 } 496 497 @Override findExtensionByNumber( ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number)498 Object findExtensionByNumber( 499 ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number) { 500 return ((ExtensionRegistry) extensionRegistry) 501 .findExtensionByNumber(((Message) defaultInstance).getDescriptorForType(), number); 502 } 503 504 @Override parseLengthPrefixedMessageSetItem( Reader reader, Object extension, ExtensionRegistryLite extensionRegistry, FieldSet<FieldDescriptor> extensions)505 void parseLengthPrefixedMessageSetItem( 506 Reader reader, 507 Object extension, 508 ExtensionRegistryLite extensionRegistry, 509 FieldSet<FieldDescriptor> extensions) 510 throws IOException { 511 ExtensionRegistry.ExtensionInfo extensionInfo = (ExtensionRegistry.ExtensionInfo) extension; 512 513 if (ExtensionRegistryLite.isEagerlyParseMessageSets()) { 514 Object value = 515 reader.readMessage(extensionInfo.defaultInstance.getClass(), extensionRegistry); 516 extensions.setField(extensionInfo.descriptor, value); 517 } else { 518 extensions.setField( 519 extensionInfo.descriptor, 520 new LazyField(extensionInfo.defaultInstance, extensionRegistry, reader.readBytes())); 521 } 522 } 523 524 @Override parseMessageSetItem( ByteString data, Object extension, ExtensionRegistryLite extensionRegistry, FieldSet<FieldDescriptor> extensions)525 void parseMessageSetItem( 526 ByteString data, 527 Object extension, 528 ExtensionRegistryLite extensionRegistry, 529 FieldSet<FieldDescriptor> extensions) 530 throws IOException { 531 ExtensionRegistry.ExtensionInfo extensionInfo = (ExtensionRegistry.ExtensionInfo) extension; 532 Object value = extensionInfo.defaultInstance.newBuilderForType().buildPartial(); 533 534 if (ExtensionRegistryLite.isEagerlyParseMessageSets()) { 535 Reader reader = BinaryReader.newInstance(ByteBuffer.wrap(data.toByteArray()), true); 536 Protobuf.getInstance().mergeFrom(value, reader, extensionRegistry); 537 extensions.setField(extensionInfo.descriptor, value); 538 539 if (reader.getFieldNumber() != Reader.READ_DONE) { 540 throw InvalidProtocolBufferException.invalidEndTag(); 541 } 542 } else { 543 extensions.setField( 544 extensionInfo.descriptor, 545 new LazyField(extensionInfo.defaultInstance, extensionRegistry, data)); 546 } 547 } 548 } 549