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