DynamicMessage.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using Google.ProtocolBuffers.Descriptors;
  6. namespace Google.ProtocolBuffers {
  7. /// <summary>
  8. /// An implementation of IMessage that can represent arbitrary types, given a MessageaDescriptor.
  9. /// </summary>
  10. public class DynamicMessage : AbstractMessage<DynamicMessage, DynamicMessage.Builder> {
  11. private readonly MessageDescriptor type;
  12. private readonly FieldSet fields;
  13. private readonly UnknownFieldSet unknownFields;
  14. private int memoizedSize = -1;
  15. /// <summary>
  16. /// Creates a DynamicMessage with the given FieldSet.
  17. /// </summary>
  18. /// <param name="type"></param>
  19. /// <param name="fields"></param>
  20. /// <param name="unknownFields"></param>
  21. private DynamicMessage(MessageDescriptor type, FieldSet fields, UnknownFieldSet unknownFields) {
  22. this.type = type;
  23. this.fields = fields;
  24. this.unknownFields = unknownFields;
  25. }
  26. /// <summary>
  27. /// Returns a DynamicMessage representing the default instance of the given type.
  28. /// </summary>
  29. /// <param name="type"></param>
  30. /// <returns></returns>
  31. public static DynamicMessage GetDefaultInstance(MessageDescriptor type) {
  32. return new DynamicMessage(type, FieldSet.DefaultInstance, UnknownFieldSet.DefaultInstance);
  33. }
  34. /// <summary>
  35. /// Parses a message of the given type from the given stream.
  36. /// </summary>
  37. public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input) {
  38. Builder builder = CreateBuilder(type);
  39. Builder dynamicBuilder = builder.MergeFrom(input);
  40. return dynamicBuilder.BuildParsed();
  41. }
  42. /// <summary>
  43. /// Parse a message of the given type from the given stream and extension registry.
  44. /// </summary>
  45. /// <param name="type"></param>
  46. /// <param name="input"></param>
  47. /// <param name="extensionRegistry"></param>
  48. /// <returns></returns>
  49. public static DynamicMessage ParseFrom(MessageDescriptor type, CodedInputStream input, ExtensionRegistry extensionRegistry) {
  50. Builder builder = CreateBuilder(type);
  51. Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry);
  52. return dynamicBuilder.BuildParsed();
  53. }
  54. /// <summary>
  55. /// Parses a message of the given type from the given stream.
  56. /// </summary>
  57. public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input) {
  58. Builder builder = CreateBuilder(type);
  59. Builder dynamicBuilder = builder.MergeFrom(input);
  60. return dynamicBuilder.BuildParsed();
  61. }
  62. /// <summary>
  63. /// Parse a message of the given type from the given stream and extension registry.
  64. /// </summary>
  65. /// <param name="type"></param>
  66. /// <param name="input"></param>
  67. /// <param name="extensionRegistry"></param>
  68. /// <returns></returns>
  69. public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input, ExtensionRegistry extensionRegistry) {
  70. Builder builder = CreateBuilder(type);
  71. Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry);
  72. return dynamicBuilder.BuildParsed();
  73. }
  74. /// <summary>
  75. /// Parse <paramref name="data"/> as a message of the given type and return it.
  76. /// </summary>
  77. public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data) {
  78. Builder builder = CreateBuilder(type);
  79. Builder dynamicBuilder = builder.MergeFrom(data);
  80. return dynamicBuilder.BuildParsed();
  81. }
  82. /// <summary>
  83. /// Parse <paramref name="data"/> as a message of the given type and return it.
  84. /// </summary>
  85. public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data, ExtensionRegistry extensionRegistry) {
  86. Builder builder = CreateBuilder(type);
  87. Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry);
  88. return dynamicBuilder.BuildParsed();
  89. }
  90. /// <summary>
  91. /// Parse <paramref name="data"/> as a message of the given type and return it.
  92. /// </summary>
  93. public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data) {
  94. Builder builder = CreateBuilder(type);
  95. Builder dynamicBuilder = builder.MergeFrom(data);
  96. return dynamicBuilder.BuildParsed();
  97. }
  98. /// <summary>
  99. /// Parse <paramref name="data"/> as a message of the given type and return it.
  100. /// </summary>
  101. public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data, ExtensionRegistry extensionRegistry) {
  102. Builder builder = CreateBuilder(type);
  103. Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry);
  104. return dynamicBuilder.BuildParsed();
  105. }
  106. /// <summary>
  107. /// Constructs a builder for the given type.
  108. /// </summary>
  109. public static Builder CreateBuilder(MessageDescriptor type) {
  110. return new Builder(type);
  111. }
  112. /// <summary>
  113. /// Constructs a builder for a message of the same type as <paramref name="prototype"/>,
  114. /// and initializes it with the same contents.
  115. /// </summary>
  116. /// <param name="prototype"></param>
  117. /// <returns></returns>
  118. public static Builder CreateBuilder(IMessage prototype) {
  119. return new Builder(prototype.DescriptorForType).MergeFrom(prototype);
  120. }
  121. // -----------------------------------------------------------------
  122. // Implementation of IMessage interface.
  123. public override MessageDescriptor DescriptorForType {
  124. get { return type; }
  125. }
  126. public override DynamicMessage DefaultInstanceForType {
  127. get { return GetDefaultInstance(type); }
  128. }
  129. public override IDictionary<FieldDescriptor, object> AllFields {
  130. get { return fields.AllFields; }
  131. }
  132. public override bool HasField(FieldDescriptor field) {
  133. VerifyContainingType(field);
  134. return fields.HasField(field);
  135. }
  136. public override object this[FieldDescriptor field] {
  137. get {
  138. VerifyContainingType(field);
  139. object result = fields[field];
  140. if (result == null) {
  141. result = GetDefaultInstance(field.MessageType);
  142. }
  143. return result;
  144. }
  145. }
  146. public override int GetRepeatedFieldCount(FieldDescriptor field) {
  147. VerifyContainingType(field);
  148. return fields.GetRepeatedFieldCount(field);
  149. }
  150. public override object this[FieldDescriptor field, int index] {
  151. get {
  152. VerifyContainingType(field);
  153. return fields[field, index];
  154. }
  155. }
  156. public override UnknownFieldSet UnknownFields {
  157. get { return unknownFields; }
  158. }
  159. public bool Initialized {
  160. get { return fields.IsInitializedWithRespectTo(type); }
  161. }
  162. public override void WriteTo(CodedOutputStream output) {
  163. fields.WriteTo(output);
  164. if (type.Options.MessageSetWireFormat) {
  165. unknownFields.WriteAsMessageSetTo(output);
  166. } else {
  167. unknownFields.WriteTo(output);
  168. }
  169. }
  170. public override int SerializedSize {
  171. get {
  172. int size = memoizedSize;
  173. if (size != -1) return size;
  174. size = fields.SerializedSize;
  175. if (type.Options.MessageSetWireFormat) {
  176. size += unknownFields.SerializedSizeAsMessageSet;
  177. } else {
  178. size += unknownFields.SerializedSize;
  179. }
  180. memoizedSize = size;
  181. return size;
  182. }
  183. }
  184. public override Builder CreateBuilderForType() {
  185. return new Builder(type);
  186. }
  187. /// <summary>
  188. /// Verifies that the field is a field of this message.
  189. /// </summary>
  190. private void VerifyContainingType(FieldDescriptor field) {
  191. if (field.ContainingType != type) {
  192. throw new ArgumentException("FieldDescriptor does not match message type.");
  193. }
  194. }
  195. public class Builder : AbstractBuilder<DynamicMessage, DynamicMessage.Builder> {
  196. private readonly MessageDescriptor type;
  197. private FieldSet fields;
  198. private UnknownFieldSet unknownFields;
  199. internal Builder(MessageDescriptor type) {
  200. this.type = type;
  201. this.fields = FieldSet.CreateFieldSet();
  202. this.unknownFields = UnknownFieldSet.DefaultInstance;
  203. }
  204. protected override Builder ThisBuilder {
  205. get { return this; }
  206. }
  207. public override Builder Clear() {
  208. fields.Clear();
  209. return this;
  210. }
  211. public override Builder MergeFrom(IMessage other) {
  212. if (other.DescriptorForType != type) {
  213. throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
  214. }
  215. fields.MergeFrom(other);
  216. return this;
  217. }
  218. public override Builder MergeFrom(DynamicMessage other) {
  219. if (other.DescriptorForType != type) {
  220. throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
  221. }
  222. fields.MergeFrom(other);
  223. return this;
  224. }
  225. public override DynamicMessage Build() {
  226. if (!IsInitialized) {
  227. throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields));
  228. }
  229. return BuildPartial();
  230. }
  231. /// <summary>
  232. /// Helper for DynamicMessage.ParseFrom() methods to call. Throws
  233. /// InvalidProtocolBufferException
  234. /// </summary>
  235. /// <returns></returns>
  236. internal DynamicMessage BuildParsed() {
  237. if (!IsInitialized) {
  238. throw new UninitializedMessageException(new DynamicMessage(type, fields, unknownFields)).AsInvalidProtocolBufferException();
  239. }
  240. return BuildPartial();
  241. }
  242. public override DynamicMessage BuildPartial() {
  243. fields.MakeImmutable();
  244. DynamicMessage result = new DynamicMessage(type, fields, unknownFields);
  245. fields = null;
  246. unknownFields = null;
  247. return result;
  248. }
  249. public override Builder Clone() {
  250. Builder result = new Builder(type);
  251. result.fields.MergeFrom(fields);
  252. return result;
  253. }
  254. public override bool IsInitialized {
  255. get { return fields.IsInitializedWithRespectTo(type); }
  256. }
  257. public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
  258. UnknownFieldSet.Builder unknownFieldsBuilder = UnknownFieldSet.CreateBuilder(unknownFields);
  259. FieldSet.MergeFrom(input, unknownFieldsBuilder, extensionRegistry, this);
  260. unknownFields = unknownFieldsBuilder.Build();
  261. return this;
  262. }
  263. public override MessageDescriptor DescriptorForType {
  264. get { return type; }
  265. }
  266. public override DynamicMessage DefaultInstanceForType {
  267. get { return GetDefaultInstance(type); }
  268. }
  269. public override IDictionary<FieldDescriptor, object> AllFields {
  270. get { return fields.AllFields; }
  271. }
  272. public override IBuilder CreateBuilderForField(FieldDescriptor field) {
  273. VerifyContainingType(field);
  274. if (field.MappedType != MappedType.Message) {
  275. throw new ArgumentException("CreateBuilderForField is only valid for fields with message type.");
  276. }
  277. return new Builder(field.MessageType);
  278. }
  279. public override bool HasField(FieldDescriptor field) {
  280. VerifyContainingType(field);
  281. return fields.HasField(field);
  282. }
  283. public override object this[FieldDescriptor field, int index] {
  284. get {
  285. VerifyContainingType(field);
  286. return fields[field, index];
  287. }
  288. set {
  289. VerifyContainingType(field);
  290. fields[field, index] = value;
  291. }
  292. }
  293. public override object this[FieldDescriptor field] {
  294. get {
  295. VerifyContainingType(field);
  296. object result = fields[field];
  297. if (result == null) {
  298. result = GetDefaultInstance(field.MessageType);
  299. }
  300. return result;
  301. }
  302. set {
  303. VerifyContainingType(field);
  304. fields[field] = value;
  305. }
  306. }
  307. public override Builder ClearField(FieldDescriptor field) {
  308. VerifyContainingType(field);
  309. fields.ClearField(field);
  310. return this;
  311. }
  312. public override int GetRepeatedFieldCount(FieldDescriptor field) {
  313. VerifyContainingType(field);
  314. return fields.GetRepeatedFieldCount(field);
  315. }
  316. public override Builder AddRepeatedField(FieldDescriptor field, object value) {
  317. VerifyContainingType(field);
  318. fields.AddRepeatedField(field, value);
  319. return this;
  320. }
  321. public override UnknownFieldSet UnknownFields {
  322. get {
  323. return unknownFields;
  324. }
  325. set {
  326. unknownFields = value;
  327. }
  328. }
  329. /// <summary>
  330. /// Verifies that the field is a field of this message.
  331. /// </summary>
  332. /// <param name="field"></param>
  333. private void VerifyContainingType(FieldDescriptor field) {
  334. if (field.ContainingType != type) {
  335. throw new ArgumentException("FieldDescriptor does not match message type.");
  336. }
  337. }
  338. }
  339. }
  340. }