MessageSetSchema.java
Go to the documentation of this file.
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 import java.util.Iterator;
35 import java.util.Map.Entry;
36 
38 final class MessageSetSchema<T> implements Schema<T> {
39  private final MessageLite defaultInstance;
40  private final UnknownFieldSchema<?, ?> unknownFieldSchema;
41  private final boolean hasExtensions;
42  private final ExtensionSchema<?> extensionSchema;
43 
44  private MessageSetSchema(
45  UnknownFieldSchema<?, ?> unknownFieldSchema,
46  ExtensionSchema<?> extensionSchema,
47  MessageLite defaultInstance) {
48  this.unknownFieldSchema = unknownFieldSchema;
49  this.hasExtensions = extensionSchema.hasExtensions(defaultInstance);
50  this.extensionSchema = extensionSchema;
51  this.defaultInstance = defaultInstance;
52  }
53 
54  static <T> MessageSetSchema<T> newSchema(
55  UnknownFieldSchema<?, ?> unknownFieldSchema,
56  ExtensionSchema<?> extensionSchema,
57  MessageLite defaultInstance) {
58  return new MessageSetSchema<T>(unknownFieldSchema, extensionSchema, defaultInstance);
59  }
60 
61  @SuppressWarnings("unchecked")
62  @Override
63  public T newInstance() {
64  return (T) defaultInstance.newBuilderForType().buildPartial();
65  }
66 
67  @Override
68  public boolean equals(T message, T other) {
69  Object messageUnknown = unknownFieldSchema.getFromMessage(message);
70  Object otherUnknown = unknownFieldSchema.getFromMessage(other);
71  if (!messageUnknown.equals(otherUnknown)) {
72  return false;
73  }
74  if (hasExtensions) {
75  FieldSet<?> messageExtensions = extensionSchema.getExtensions(message);
76  FieldSet<?> otherExtensions = extensionSchema.getExtensions(other);
77  return messageExtensions.equals(otherExtensions);
78  }
79  return true;
80  }
81 
82  @Override
83  public int hashCode(T message) {
84  int hashCode = unknownFieldSchema.getFromMessage(message).hashCode();
85  if (hasExtensions) {
86  FieldSet<?> extensions = extensionSchema.getExtensions(message);
87  hashCode = (hashCode * 53) + extensions.hashCode();
88  }
89  return hashCode;
90  }
91 
92  @Override
93  public void mergeFrom(T message, T other) {
94  SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other);
95  if (hasExtensions) {
96  SchemaUtil.mergeExtensions(extensionSchema, message, other);
97  }
98  }
99 
100  @SuppressWarnings("unchecked")
101  @Override
102  public void writeTo(T message, Writer writer) throws IOException {
103  FieldSet<?> extensions = extensionSchema.getExtensions(message);
104  Iterator<?> iterator = extensions.iterator();
105  while (iterator.hasNext()) {
106  Entry<?, ?> extension = (Entry<?, ?>) iterator.next();
107  FieldSet.FieldDescriptorLite<?> fd = (FieldSet.FieldDescriptorLite<?>) extension.getKey();
108  if (fd.getLiteJavaType() != WireFormat.JavaType.MESSAGE || fd.isRepeated() || fd.isPacked()) {
109  throw new IllegalStateException("Found invalid MessageSet item.");
110  }
111  if (extension instanceof LazyField.LazyEntry) {
112  writer.writeMessageSetItem(
113  fd.getNumber(), ((LazyField.LazyEntry) extension).getField().toByteString());
114  } else {
115  writer.writeMessageSetItem(fd.getNumber(), extension.getValue());
116  }
117  }
118  writeUnknownFieldsHelper(unknownFieldSchema, message, writer);
119  }
120 
125  private <UT, UB> void writeUnknownFieldsHelper(
126  UnknownFieldSchema<UT, UB> unknownFieldSchema, T message, Writer writer) throws IOException {
127  unknownFieldSchema.writeAsMessageSetTo(unknownFieldSchema.getFromMessage(message), writer);
128  }
129 
130  @SuppressWarnings("ReferenceEquality")
131  @Override
132  public void mergeFrom(
133  T message, byte[] data, int position, int limit, ArrayDecoders.Registers registers)
134  throws IOException {
135  UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
136  if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
137  unknownFields = UnknownFieldSetLite.newInstance();
138  ((GeneratedMessageLite) message).unknownFields = unknownFields;
139  }
140  final FieldSet<GeneratedMessageLite.ExtensionDescriptor> extensions =
141  ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable();
142  GeneratedMessageLite.GeneratedExtension<?, ?> extension = null;
143  while (position < limit) {
144  position = ArrayDecoders.decodeVarint32(data, position, registers);
145  final int startTag = registers.int1;
146  if (startTag != WireFormat.MESSAGE_SET_ITEM_TAG) {
147  if (WireFormat.getTagWireType(startTag) == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
148  extension =
149  (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionSchema.findExtensionByNumber(
150  registers.extensionRegistry, defaultInstance,
151  WireFormat.getTagFieldNumber(startTag));
152  if (extension != null) {
153  position =
154  ArrayDecoders.decodeMessageField(
155  Protobuf.getInstance().schemaFor(
156  extension.getMessageDefaultInstance().getClass()),
157  data, position, limit, registers);
158  extensions.setField(extension.descriptor, registers.object1);
159  } else {
160  position =
161  ArrayDecoders.decodeUnknownField(
162  startTag, data, position, limit, unknownFields, registers);
163  }
164  } else {
165  position = ArrayDecoders.skipField(startTag, data, position, limit, registers);
166  }
167  continue;
168  }
169 
170  int typeId = 0;
171  ByteString rawBytes = null;
172 
173  while (position < limit) {
174  position = ArrayDecoders.decodeVarint32(data, position, registers);
175  final int tag = registers.int1;
176  final int number = WireFormat.getTagFieldNumber(tag);
177  final int wireType = WireFormat.getTagWireType(tag);
178  switch (number) {
179  case WireFormat.MESSAGE_SET_TYPE_ID:
180  if (wireType == WireFormat.WIRETYPE_VARINT) {
181  position = ArrayDecoders.decodeVarint32(data, position, registers);
182  typeId = registers.int1;
183  extension =
184  (GeneratedMessageLite.GeneratedExtension<?, ?>) extensionSchema
185  .findExtensionByNumber(registers.extensionRegistry, defaultInstance, typeId);
186  continue;
187  }
188  break;
189  case WireFormat.MESSAGE_SET_MESSAGE:
190  if (extension != null) {
191  position = ArrayDecoders.decodeMessageField(
192  Protobuf.getInstance().schemaFor(
193  extension.getMessageDefaultInstance().getClass()),
194  data, position, limit, registers);
195  extensions.setField(extension.descriptor, registers.object1);
196  continue;
197  } else {
198  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
199  position = ArrayDecoders.decodeBytes(data, position, registers);
200  rawBytes = (ByteString) registers.object1;
201  continue;
202  }
203  break;
204  }
205  default:
206  break;
207  }
208  if (tag == WireFormat.MESSAGE_SET_ITEM_END_TAG) {
209  break;
210  }
211  position = ArrayDecoders.skipField(tag, data, position, limit, registers);
212  }
213 
214  if (rawBytes != null) {
215  unknownFields.storeField(
216  WireFormat.makeTag(typeId, WireFormat.WIRETYPE_LENGTH_DELIMITED), rawBytes);
217  }
218  }
219  if (position != limit) {
220  throw InvalidProtocolBufferException.parseFailure();
221  }
222  }
223 
224  @Override
225  public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
226  throws IOException {
227  mergeFromHelper(unknownFieldSchema, extensionSchema, message, reader, extensionRegistry);
228  }
229 
234  @SuppressWarnings("unchecked")
235  private <UT, UB, ET extends FieldSet.FieldDescriptorLite<ET>> void mergeFromHelper(
236  UnknownFieldSchema<UT, UB> unknownFieldSchema,
237  ExtensionSchema<ET> extensionSchema,
238  T message,
239  Reader reader,
240  ExtensionRegistryLite extensionRegistry)
241  throws IOException {
242  UB unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
243  FieldSet<ET> extensions = extensionSchema.getMutableExtensions(message);
244  try {
245  while (true) {
246  final int number = reader.getFieldNumber();
247  if (number == Reader.READ_DONE) {
248  return;
249  }
250  if (parseMessageSetItemOrUnknownField(
251  reader,
252  extensionRegistry,
253  extensionSchema,
254  extensions,
255  unknownFieldSchema,
256  unknownFields)) {
257  continue;
258  }
259  // Done reading.
260  return;
261  }
262  } finally {
263  unknownFieldSchema.setBuilderToMessage(message, unknownFields);
264  }
265  }
266 
267  @Override
268  public void makeImmutable(T message) {
269  unknownFieldSchema.makeImmutable(message);
270  extensionSchema.makeImmutable(message);
271  }
272 
273  private <UT, UB, ET extends FieldSet.FieldDescriptorLite<ET>>
274  boolean parseMessageSetItemOrUnknownField(
275  Reader reader,
276  ExtensionRegistryLite extensionRegistry,
277  ExtensionSchema<ET> extensionSchema,
278  FieldSet<ET> extensions,
279  UnknownFieldSchema<UT, UB> unknownFieldSchema,
280  UB unknownFields)
281  throws IOException {
282  int startTag = reader.getTag();
283  if (startTag != WireFormat.MESSAGE_SET_ITEM_TAG) {
284  if (WireFormat.getTagWireType(startTag) == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
285  Object extension =
286  extensionSchema.findExtensionByNumber(
287  extensionRegistry, defaultInstance, WireFormat.getTagFieldNumber(startTag));
288  if (extension != null) {
289  extensionSchema.parseLengthPrefixedMessageSetItem(
290  reader, extension, extensionRegistry, extensions);
291  return true;
292  } else {
293  return unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader);
294  }
295  } else {
296  return reader.skipField();
297  }
298  }
299 
300  // The wire format for MessageSet is:
301  // message MessageSet {
302  // repeated group Item = 1 {
303  // required int32 typeId = 2;
304  // required bytes message = 3;
305  // }
306  // }
307  // "typeId" is the extension's field number. The extension can only be
308  // a message type, where "message" contains the encoded bytes of that
309  // message.
310  //
311  // In practice, we will probably never see a MessageSet item in which
312  // the message appears before the type ID, or where either field does not
313  // appear exactly once. However, in theory such cases are valid, so we
314  // should be prepared to accept them.
315 
316  int typeId = 0;
317  ByteString rawBytes = null; // If we encounter "message" before "typeId"
318  Object extension = null;
319 
320  // Read bytes from input, if we get it's type first then parse it eagerly,
321  // otherwise we store the raw bytes in a local variable.
322  loop:
323  while (true) {
324  final int number = reader.getFieldNumber();
325  if (number == Reader.READ_DONE) {
326  break;
327  }
328 
329  final int tag = reader.getTag();
330  if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
331  typeId = reader.readUInt32();
332  extension =
333  extensionSchema.findExtensionByNumber(extensionRegistry, defaultInstance, typeId);
334  continue;
335  } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
336  if (extension != null) {
337  extensionSchema.parseLengthPrefixedMessageSetItem(
338  reader, extension, extensionRegistry, extensions);
339  continue;
340  }
341  // We haven't seen a type ID yet or we want parse message lazily.
342  rawBytes = reader.readBytes();
343  continue;
344  } else {
345  if (!reader.skipField()) {
346  break loop; // End of group
347  }
348  }
349  }
350 
351  if (reader.getTag() != WireFormat.MESSAGE_SET_ITEM_END_TAG) {
352  throw InvalidProtocolBufferException.invalidEndTag();
353  }
354 
355  // If there are any rawBytes left, it means the message content appears before the type ID.
356  if (rawBytes != null) {
357  if (extension != null) { // We known the type
358  // TODO(xiaofeng): Instead of reading into a temporary ByteString, maybe there is a way
359  // to read directly from Reader to the submessage?
360  extensionSchema.parseMessageSetItem(rawBytes, extension, extensionRegistry, extensions);
361  } else {
362  unknownFieldSchema.addLengthDelimited(unknownFields, typeId, rawBytes);
363  }
364  }
365  return true;
366  }
367 
368  @Override
369  public final boolean isInitialized(T message) {
370  FieldSet<?> extensions = extensionSchema.getExtensions(message);
371  return extensions.isInitialized();
372  }
373 
374  @Override
375  public int getSerializedSize(T message) {
376  int size = 0;
377 
378  size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);
379 
380  if (hasExtensions) {
381  size += extensionSchema.getExtensions(message).getMessageSetSerializedSize();
382  }
383 
384  return size;
385  }
386 
387  private <UT, UB> int getUnknownFieldsSerializedSize(
388  UnknownFieldSchema<UT, UB> schema, T message) {
389  UT unknowns = schema.getFromMessage(message);
390  return schema.getSerializedSizeAsMessageSet(unknowns);
391  }
392 }
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: src/google/protobuf/descriptor.h:2001
T
#define T(upbtypeconst, upbtype, ctype, default_value)
isInitialized
ROSCPP_DECL bool isInitialized()
size
#define size
Definition: glcorearb.h:2944
position
intern position
Definition: array.c:487
java
size
GLsizeiptr size
Definition: glcorearb.h:2943
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
number
double number
Definition: cJSON.h:326
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:57