/thirdparty/breakpad/third_party/protobuf/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java

http://github.com/tomahawk-player/tomahawk · Java · 438 lines · 299 code · 64 blank · 75 comment · 37 complexity · a63dde7ca05b8602efd7047fea72b475 MD5 · raw file

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  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. package com.google.protobuf;
  31. import com.google.protobuf.Descriptors.Descriptor;
  32. import com.google.protobuf.Descriptors.FieldDescriptor;
  33. import java.io.InputStream;
  34. import java.io.IOException;
  35. import java.util.Map;
  36. /**
  37. * An implementation of {@link Message} that can represent arbitrary types,
  38. * given a {@link Descriptors.Descriptor}.
  39. *
  40. * @author kenton@google.com Kenton Varda
  41. */
  42. public final class DynamicMessage extends AbstractMessage {
  43. private final Descriptor type;
  44. private final FieldSet<FieldDescriptor> fields;
  45. private final UnknownFieldSet unknownFields;
  46. private int memoizedSize = -1;
  47. /**
  48. * Construct a {@code DynamicMessage} using the given {@code FieldSet}.
  49. */
  50. private DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields,
  51. UnknownFieldSet unknownFields) {
  52. this.type = type;
  53. this.fields = fields;
  54. this.unknownFields = unknownFields;
  55. }
  56. /**
  57. * Get a {@code DynamicMessage} representing the default instance of the
  58. * given type.
  59. */
  60. public static DynamicMessage getDefaultInstance(Descriptor type) {
  61. return new DynamicMessage(type, FieldSet.<FieldDescriptor>emptySet(),
  62. UnknownFieldSet.getDefaultInstance());
  63. }
  64. /** Parse a message of the given type from the given input stream. */
  65. public static DynamicMessage parseFrom(Descriptor type,
  66. CodedInputStream input)
  67. throws IOException {
  68. return newBuilder(type).mergeFrom(input).buildParsed();
  69. }
  70. /** Parse a message of the given type from the given input stream. */
  71. public static DynamicMessage parseFrom(
  72. Descriptor type,
  73. CodedInputStream input,
  74. ExtensionRegistry extensionRegistry)
  75. throws IOException {
  76. return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
  77. }
  78. /** Parse {@code data} as a message of the given type and return it. */
  79. public static DynamicMessage parseFrom(Descriptor type, ByteString data)
  80. throws InvalidProtocolBufferException {
  81. return newBuilder(type).mergeFrom(data).buildParsed();
  82. }
  83. /** Parse {@code data} as a message of the given type and return it. */
  84. public static DynamicMessage parseFrom(Descriptor type, ByteString data,
  85. ExtensionRegistry extensionRegistry)
  86. throws InvalidProtocolBufferException {
  87. return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
  88. }
  89. /** Parse {@code data} as a message of the given type and return it. */
  90. public static DynamicMessage parseFrom(Descriptor type, byte[] data)
  91. throws InvalidProtocolBufferException {
  92. return newBuilder(type).mergeFrom(data).buildParsed();
  93. }
  94. /** Parse {@code data} as a message of the given type and return it. */
  95. public static DynamicMessage parseFrom(Descriptor type, byte[] data,
  96. ExtensionRegistry extensionRegistry)
  97. throws InvalidProtocolBufferException {
  98. return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
  99. }
  100. /** Parse a message of the given type from {@code input} and return it. */
  101. public static DynamicMessage parseFrom(Descriptor type, InputStream input)
  102. throws IOException {
  103. return newBuilder(type).mergeFrom(input).buildParsed();
  104. }
  105. /** Parse a message of the given type from {@code input} and return it. */
  106. public static DynamicMessage parseFrom(Descriptor type, InputStream input,
  107. ExtensionRegistry extensionRegistry)
  108. throws IOException {
  109. return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
  110. }
  111. /** Construct a {@link Message.Builder} for the given type. */
  112. public static Builder newBuilder(Descriptor type) {
  113. return new Builder(type);
  114. }
  115. /**
  116. * Construct a {@link Message.Builder} for a message of the same type as
  117. * {@code prototype}, and initialize it with {@code prototype}'s contents.
  118. */
  119. public static Builder newBuilder(Message prototype) {
  120. return new Builder(prototype.getDescriptorForType()).mergeFrom(prototype);
  121. }
  122. // -----------------------------------------------------------------
  123. // Implementation of Message interface.
  124. public Descriptor getDescriptorForType() {
  125. return type;
  126. }
  127. public DynamicMessage getDefaultInstanceForType() {
  128. return getDefaultInstance(type);
  129. }
  130. public Map<FieldDescriptor, Object> getAllFields() {
  131. return fields.getAllFields();
  132. }
  133. public boolean hasField(FieldDescriptor field) {
  134. verifyContainingType(field);
  135. return fields.hasField(field);
  136. }
  137. public Object getField(FieldDescriptor field) {
  138. verifyContainingType(field);
  139. Object result = fields.getField(field);
  140. if (result == null) {
  141. if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
  142. result = getDefaultInstance(field.getMessageType());
  143. } else {
  144. result = field.getDefaultValue();
  145. }
  146. }
  147. return result;
  148. }
  149. public int getRepeatedFieldCount(FieldDescriptor field) {
  150. verifyContainingType(field);
  151. return fields.getRepeatedFieldCount(field);
  152. }
  153. public Object getRepeatedField(FieldDescriptor field, int index) {
  154. verifyContainingType(field);
  155. return fields.getRepeatedField(field, index);
  156. }
  157. public UnknownFieldSet getUnknownFields() {
  158. return unknownFields;
  159. }
  160. private static boolean isInitialized(Descriptor type,
  161. FieldSet<FieldDescriptor> fields) {
  162. // Check that all required fields are present.
  163. for (final FieldDescriptor field : type.getFields()) {
  164. if (field.isRequired()) {
  165. if (!fields.hasField(field)) {
  166. return false;
  167. }
  168. }
  169. }
  170. // Check that embedded messages are initialized.
  171. return fields.isInitialized();
  172. }
  173. public boolean isInitialized() {
  174. return isInitialized(type, fields);
  175. }
  176. public void writeTo(CodedOutputStream output) throws IOException {
  177. if (type.getOptions().getMessageSetWireFormat()) {
  178. fields.writeMessageSetTo(output);
  179. unknownFields.writeAsMessageSetTo(output);
  180. } else {
  181. fields.writeTo(output);
  182. unknownFields.writeTo(output);
  183. }
  184. }
  185. public int getSerializedSize() {
  186. int size = memoizedSize;
  187. if (size != -1) return size;
  188. if (type.getOptions().getMessageSetWireFormat()) {
  189. size = fields.getMessageSetSerializedSize();
  190. size += unknownFields.getSerializedSizeAsMessageSet();
  191. } else {
  192. size = fields.getSerializedSize();
  193. size += unknownFields.getSerializedSize();
  194. }
  195. memoizedSize = size;
  196. return size;
  197. }
  198. public Builder newBuilderForType() {
  199. return new Builder(type);
  200. }
  201. public Builder toBuilder() {
  202. return newBuilderForType().mergeFrom(this);
  203. }
  204. /** Verifies that the field is a field of this message. */
  205. private void verifyContainingType(FieldDescriptor field) {
  206. if (field.getContainingType() != type) {
  207. throw new IllegalArgumentException(
  208. "FieldDescriptor does not match message type.");
  209. }
  210. }
  211. // =================================================================
  212. /**
  213. * Builder for {@link DynamicMessage}s.
  214. */
  215. public static final class Builder extends AbstractMessage.Builder<Builder> {
  216. private final Descriptor type;
  217. private FieldSet<FieldDescriptor> fields;
  218. private UnknownFieldSet unknownFields;
  219. /** Construct a {@code Builder} for the given type. */
  220. private Builder(Descriptor type) {
  221. this.type = type;
  222. this.fields = FieldSet.newFieldSet();
  223. this.unknownFields = UnknownFieldSet.getDefaultInstance();
  224. }
  225. // ---------------------------------------------------------------
  226. // Implementation of Message.Builder interface.
  227. public Builder clear() {
  228. if (fields == null) {
  229. throw new IllegalStateException("Cannot call clear() after build().");
  230. }
  231. fields.clear();
  232. return this;
  233. }
  234. public Builder mergeFrom(Message other) {
  235. if (other instanceof DynamicMessage) {
  236. // This should be somewhat faster than calling super.mergeFrom().
  237. DynamicMessage otherDynamicMessage = (DynamicMessage) other;
  238. if (otherDynamicMessage.type != type) {
  239. throw new IllegalArgumentException(
  240. "mergeFrom(Message) can only merge messages of the same type.");
  241. }
  242. fields.mergeFrom(otherDynamicMessage.fields);
  243. mergeUnknownFields(otherDynamicMessage.unknownFields);
  244. return this;
  245. } else {
  246. return super.mergeFrom(other);
  247. }
  248. }
  249. public DynamicMessage build() {
  250. // If fields == null, we'll throw an appropriate exception later.
  251. if (fields != null && !isInitialized()) {
  252. throw newUninitializedMessageException(
  253. new DynamicMessage(type, fields, unknownFields));
  254. }
  255. return buildPartial();
  256. }
  257. /**
  258. * Helper for DynamicMessage.parseFrom() methods to call. Throws
  259. * {@link InvalidProtocolBufferException} instead of
  260. * {@link UninitializedMessageException}.
  261. */
  262. private DynamicMessage buildParsed() throws InvalidProtocolBufferException {
  263. if (!isInitialized()) {
  264. throw newUninitializedMessageException(
  265. new DynamicMessage(type, fields, unknownFields))
  266. .asInvalidProtocolBufferException();
  267. }
  268. return buildPartial();
  269. }
  270. public DynamicMessage buildPartial() {
  271. if (fields == null) {
  272. throw new IllegalStateException(
  273. "build() has already been called on this Builder.");
  274. }
  275. fields.makeImmutable();
  276. DynamicMessage result =
  277. new DynamicMessage(type, fields, unknownFields);
  278. fields = null;
  279. unknownFields = null;
  280. return result;
  281. }
  282. public Builder clone() {
  283. Builder result = new Builder(type);
  284. result.fields.mergeFrom(fields);
  285. return result;
  286. }
  287. public boolean isInitialized() {
  288. return DynamicMessage.isInitialized(type, fields);
  289. }
  290. public Descriptor getDescriptorForType() {
  291. return type;
  292. }
  293. public DynamicMessage getDefaultInstanceForType() {
  294. return getDefaultInstance(type);
  295. }
  296. public Map<FieldDescriptor, Object> getAllFields() {
  297. return fields.getAllFields();
  298. }
  299. public Builder newBuilderForField(FieldDescriptor field) {
  300. verifyContainingType(field);
  301. if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
  302. throw new IllegalArgumentException(
  303. "newBuilderForField is only valid for fields with message type.");
  304. }
  305. return new Builder(field.getMessageType());
  306. }
  307. public boolean hasField(FieldDescriptor field) {
  308. verifyContainingType(field);
  309. return fields.hasField(field);
  310. }
  311. public Object getField(FieldDescriptor field) {
  312. verifyContainingType(field);
  313. Object result = fields.getField(field);
  314. if (result == null) {
  315. if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
  316. result = getDefaultInstance(field.getMessageType());
  317. } else {
  318. result = field.getDefaultValue();
  319. }
  320. }
  321. return result;
  322. }
  323. public Builder setField(FieldDescriptor field, Object value) {
  324. verifyContainingType(field);
  325. fields.setField(field, value);
  326. return this;
  327. }
  328. public Builder clearField(FieldDescriptor field) {
  329. verifyContainingType(field);
  330. fields.clearField(field);
  331. return this;
  332. }
  333. public int getRepeatedFieldCount(FieldDescriptor field) {
  334. verifyContainingType(field);
  335. return fields.getRepeatedFieldCount(field);
  336. }
  337. public Object getRepeatedField(FieldDescriptor field, int index) {
  338. verifyContainingType(field);
  339. return fields.getRepeatedField(field, index);
  340. }
  341. public Builder setRepeatedField(FieldDescriptor field,
  342. int index, Object value) {
  343. verifyContainingType(field);
  344. fields.setRepeatedField(field, index, value);
  345. return this;
  346. }
  347. public Builder addRepeatedField(FieldDescriptor field, Object value) {
  348. verifyContainingType(field);
  349. fields.addRepeatedField(field, value);
  350. return this;
  351. }
  352. public UnknownFieldSet getUnknownFields() {
  353. return unknownFields;
  354. }
  355. public Builder setUnknownFields(UnknownFieldSet unknownFields) {
  356. this.unknownFields = unknownFields;
  357. return this;
  358. }
  359. public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
  360. this.unknownFields =
  361. UnknownFieldSet.newBuilder(this.unknownFields)
  362. .mergeFrom(unknownFields)
  363. .build();
  364. return this;
  365. }
  366. /** Verifies that the field is a field of this message. */
  367. private void verifyContainingType(FieldDescriptor field) {
  368. if (field.getContainingType() != type) {
  369. throw new IllegalArgumentException(
  370. "FieldDescriptor does not match message type.");
  371. }
  372. }
  373. }
  374. }