PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/java/src/main/java/com/google/protobuf/DynamicMessage.java

https://bitbucket.org/Abd4llA/test
Java | 405 lines | 271 code | 63 blank | 71 comment | 20 complexity | c4f206d1b0a8a5fdd59d785f954cbe42 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 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 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.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. result = getDefaultInstance(field.getMessageType());
  142. }
  143. return result;
  144. }
  145. public int getRepeatedFieldCount(FieldDescriptor field) {
  146. verifyContainingType(field);
  147. return fields.getRepeatedFieldCount(field);
  148. }
  149. public Object getRepeatedField(FieldDescriptor field, int index) {
  150. verifyContainingType(field);
  151. return fields.getRepeatedField(field, index);
  152. }
  153. public UnknownFieldSet getUnknownFields() {
  154. return unknownFields;
  155. }
  156. public boolean isInitialized() {
  157. return fields.isInitialized(type);
  158. }
  159. public void writeTo(CodedOutputStream output) throws IOException {
  160. fields.writeTo(output);
  161. if (type.getOptions().getMessageSetWireFormat()) {
  162. unknownFields.writeAsMessageSetTo(output);
  163. } else {
  164. unknownFields.writeTo(output);
  165. }
  166. }
  167. public int getSerializedSize() {
  168. int size = memoizedSize;
  169. if (size != -1) return size;
  170. size = fields.getSerializedSize();
  171. if (type.getOptions().getMessageSetWireFormat()) {
  172. size += unknownFields.getSerializedSizeAsMessageSet();
  173. } else {
  174. size += unknownFields.getSerializedSize();
  175. }
  176. memoizedSize = size;
  177. return size;
  178. }
  179. public Builder newBuilderForType() {
  180. return new Builder(type);
  181. }
  182. /** Verifies that the field is a field of this message. */
  183. private void verifyContainingType(FieldDescriptor field) {
  184. if (field.getContainingType() != type) {
  185. throw new IllegalArgumentException(
  186. "FieldDescriptor does not match message type.");
  187. }
  188. }
  189. // =================================================================
  190. /**
  191. * Builder for {@link DynamicMessage}s.
  192. */
  193. public static final class Builder extends AbstractMessage.Builder<Builder> {
  194. private final Descriptor type;
  195. private FieldSet fields;
  196. private UnknownFieldSet unknownFields;
  197. /** Construct a {@code Builder} for the given type. */
  198. private Builder(Descriptor type) {
  199. this.type = type;
  200. this.fields = FieldSet.newFieldSet();
  201. this.unknownFields = UnknownFieldSet.getDefaultInstance();
  202. }
  203. // ---------------------------------------------------------------
  204. // Implementation of Message.Builder interface.
  205. public Builder clear() {
  206. fields.clear();
  207. return this;
  208. }
  209. public Builder mergeFrom(Message other) {
  210. if (other.getDescriptorForType() != type) {
  211. throw new IllegalArgumentException(
  212. "mergeFrom(Message) can only merge messages of the same type.");
  213. }
  214. fields.mergeFrom(other);
  215. return this;
  216. }
  217. public DynamicMessage build() {
  218. if (!isInitialized()) {
  219. throw new UninitializedMessageException(
  220. new DynamicMessage(type, fields, unknownFields));
  221. }
  222. return buildPartial();
  223. }
  224. /**
  225. * Helper for DynamicMessage.parseFrom() methods to call. Throws
  226. * {@link InvalidProtocolBufferException} instead of
  227. * {@link UninitializedMessageException}.
  228. */
  229. private DynamicMessage buildParsed() throws InvalidProtocolBufferException {
  230. if (!isInitialized()) {
  231. throw new UninitializedMessageException(
  232. new DynamicMessage(type, fields, unknownFields))
  233. .asInvalidProtocolBufferException();
  234. }
  235. return buildPartial();
  236. }
  237. public DynamicMessage buildPartial() {
  238. fields.makeImmutable();
  239. DynamicMessage result =
  240. new DynamicMessage(type, fields, unknownFields);
  241. fields = null;
  242. unknownFields = null;
  243. return result;
  244. }
  245. public Builder clone() {
  246. Builder result = new Builder(type);
  247. result.fields.mergeFrom(fields);
  248. return result;
  249. }
  250. public boolean isInitialized() {
  251. return fields.isInitialized(type);
  252. }
  253. public Builder mergeFrom(CodedInputStream input,
  254. ExtensionRegistry extensionRegistry)
  255. throws IOException {
  256. UnknownFieldSet.Builder unknownFieldsBuilder =
  257. UnknownFieldSet.newBuilder(unknownFields);
  258. fields.mergeFrom(input, unknownFieldsBuilder, extensionRegistry, this);
  259. unknownFields = unknownFieldsBuilder.build();
  260. return this;
  261. }
  262. public Descriptor getDescriptorForType() {
  263. return type;
  264. }
  265. public DynamicMessage getDefaultInstanceForType() {
  266. return getDefaultInstance(type);
  267. }
  268. public Map<FieldDescriptor, Object> getAllFields() {
  269. return fields.getAllFields();
  270. }
  271. public Builder newBuilderForField(FieldDescriptor field) {
  272. verifyContainingType(field);
  273. if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
  274. throw new IllegalArgumentException(
  275. "newBuilderForField is only valid for fields with message type.");
  276. }
  277. return new Builder(field.getMessageType());
  278. }
  279. public boolean hasField(FieldDescriptor field) {
  280. verifyContainingType(field);
  281. return fields.hasField(field);
  282. }
  283. public Object getField(FieldDescriptor field) {
  284. verifyContainingType(field);
  285. Object result = fields.getField(field);
  286. if (result == null) {
  287. result = getDefaultInstance(field.getMessageType());
  288. }
  289. return result;
  290. }
  291. public Builder setField(FieldDescriptor field, Object value) {
  292. verifyContainingType(field);
  293. fields.setField(field, value);
  294. return this;
  295. }
  296. public Builder clearField(FieldDescriptor field) {
  297. verifyContainingType(field);
  298. fields.clearField(field);
  299. return this;
  300. }
  301. public int getRepeatedFieldCount(FieldDescriptor field) {
  302. verifyContainingType(field);
  303. return fields.getRepeatedFieldCount(field);
  304. }
  305. public Object getRepeatedField(FieldDescriptor field, int index) {
  306. verifyContainingType(field);
  307. return fields.getRepeatedField(field, index);
  308. }
  309. public Builder setRepeatedField(FieldDescriptor field,
  310. int index, Object value) {
  311. verifyContainingType(field);
  312. fields.setRepeatedField(field, index, value);
  313. return this;
  314. }
  315. public Builder addRepeatedField(FieldDescriptor field, Object value) {
  316. verifyContainingType(field);
  317. fields.addRepeatedField(field, value);
  318. return this;
  319. }
  320. public UnknownFieldSet getUnknownFields() {
  321. return unknownFields;
  322. }
  323. public Builder setUnknownFields(UnknownFieldSet unknownFields) {
  324. this.unknownFields = unknownFields;
  325. return this;
  326. }
  327. public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
  328. this.unknownFields =
  329. UnknownFieldSet.newBuilder(this.unknownFields)
  330. .mergeFrom(unknownFields)
  331. .build();
  332. return this;
  333. }
  334. /** Verifies that the field is a field of this message. */
  335. private void verifyContainingType(FieldDescriptor field) {
  336. if (field.getContainingType() != type) {
  337. throw new IllegalArgumentException(
  338. "FieldDescriptor does not match message type.");
  339. }
  340. }
  341. }
  342. }