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