GeneratedBuilder.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using Google.ProtocolBuffers.Collections;
  6. using Google.ProtocolBuffers.Descriptors;
  7. using System.IO;
  8. using Google.ProtocolBuffers.FieldAccess;
  9. namespace Google.ProtocolBuffers {
  10. /// <summary>
  11. /// All generated protocol message builder classes extend this class. It implements
  12. /// most of the IBuilder interface using reflection. Users can ignore this class
  13. /// as an implementation detail.
  14. /// </summary>
  15. public abstract class GeneratedBuilder<TMessage, TBuilder> : AbstractBuilder<TMessage, TBuilder>
  16. where TMessage : GeneratedMessage <TMessage, TBuilder>
  17. where TBuilder : GeneratedBuilder<TMessage, TBuilder> {
  18. /// <summary>
  19. /// Returns the message being built at the moment.
  20. /// </summary>
  21. protected abstract TMessage MessageBeingBuilt { get; }
  22. protected internal FieldAccessorTable InternalFieldAccessors {
  23. get { return MessageBeingBuilt.FieldAccesseorsFromBuilder; }
  24. }
  25. public override bool IsInitialized {
  26. get { return MessageBeingBuilt.IsInitialized; }
  27. }
  28. public override IDictionary<FieldDescriptor, object> AllFields {
  29. get { return MessageBeingBuilt.AllFields; }
  30. }
  31. public override object this[FieldDescriptor field] {
  32. get {
  33. // For repeated fields, the underlying list object is still modifiable at this point.
  34. // Make sure not to expose the modifiable list to the caller.
  35. return field.IsRepeated
  36. ? InternalFieldAccessors[field].GetRepeatedWrapper(this)
  37. : MessageBeingBuilt[field];
  38. }
  39. set {
  40. InternalFieldAccessors[field].SetValue(ThisBuilder, value);
  41. }
  42. }
  43. /// <summary>
  44. /// Adds all of the specified values to the given collection.
  45. /// </summary>
  46. protected void AddRange<T>(IEnumerable<T> source, IList<T> destination) {
  47. List<T> list = destination as List<T>;
  48. if (list != null) {
  49. list.AddRange(source);
  50. } else {
  51. foreach (T element in source) {
  52. destination.Add(element);
  53. }
  54. }
  55. }
  56. /// <summary>
  57. /// Called by derived classes to parse an unknown field.
  58. /// </summary>
  59. /// <returns>true unless the tag is an end-group tag</returns>
  60. protected virtual bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields,
  61. ExtensionRegistry extensionRegistry, uint tag) {
  62. return unknownFields.MergeFieldFrom(tag, input);
  63. }
  64. public override MessageDescriptor DescriptorForType {
  65. get { return MessageBeingBuilt.DescriptorForType; }
  66. }
  67. public override int GetRepeatedFieldCount(FieldDescriptor field) {
  68. return MessageBeingBuilt.GetRepeatedFieldCount(field);
  69. }
  70. public override object this[FieldDescriptor field, int index] {
  71. get { return MessageBeingBuilt[field, index]; }
  72. set { InternalFieldAccessors[field].SetRepeated(this, index, value); }
  73. }
  74. public override bool HasField(FieldDescriptor field) {
  75. return MessageBeingBuilt.HasField(field);
  76. }
  77. public override IBuilder CreateBuilderForField(FieldDescriptor field) {
  78. return InternalFieldAccessors[field].CreateBuilder();
  79. }
  80. public override TBuilder ClearField(FieldDescriptor field) {
  81. InternalFieldAccessors[field].Clear(this);
  82. return ThisBuilder;
  83. }
  84. public override TBuilder MergeFrom(TMessage other) {
  85. if (other.DescriptorForType != InternalFieldAccessors.Descriptor) {
  86. throw new ArgumentException("Message type mismatch");
  87. }
  88. foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
  89. FieldDescriptor field = entry.Key;
  90. if (field.IsRepeated) {
  91. // Concatenate repeated fields
  92. foreach (object element in (IEnumerable)entry.Value) {
  93. AddRepeatedField(field, element);
  94. }
  95. } else if (field.MappedType == MappedType.Message && HasField(field)) {
  96. // Merge singular embedded messages
  97. IMessage oldValue = (IMessage)this[field];
  98. this[field] = oldValue.WeakCreateBuilderForType()
  99. .WeakMergeFrom(oldValue)
  100. .WeakMergeFrom((IMessage)entry.Value)
  101. .WeakBuildPartial();
  102. } else {
  103. // Just overwrite
  104. this[field] = entry.Value;
  105. }
  106. }
  107. return ThisBuilder;
  108. }
  109. public override TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) {
  110. TMessage result = MessageBeingBuilt;
  111. result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields)
  112. .MergeFrom(unknownFields)
  113. .Build());
  114. return ThisBuilder;
  115. }
  116. public override TBuilder AddRepeatedField(FieldDescriptor field, object value) {
  117. InternalFieldAccessors[field].AddRepeated(this, value);
  118. return ThisBuilder;
  119. }
  120. /// <summary>
  121. /// Like Build(), but will wrap UninitializedMessageException in
  122. /// InvalidProtocolBufferException.
  123. /// TODO(jonskeet): This used to be generated for each class. Find out why.
  124. /// </summary>
  125. public TMessage BuildParsed() {
  126. if (!IsInitialized) {
  127. throw new UninitializedMessageException(MessageBeingBuilt).AsInvalidProtocolBufferException();
  128. }
  129. return BuildPartial();
  130. }
  131. /// <summary>
  132. /// Implementation of <see cref="IBuilder{TMessage, TBuilder}.Build" />.
  133. /// TODO(jonskeet): This used to be generated for each class. Find out why.
  134. /// </summary>
  135. public override TMessage Build() {
  136. if (!IsInitialized) {
  137. throw new UninitializedMessageException(MessageBeingBuilt);
  138. }
  139. return BuildPartial();
  140. }
  141. public override UnknownFieldSet UnknownFields {
  142. get { return MessageBeingBuilt.UnknownFields; }
  143. set { MessageBeingBuilt.SetUnknownFields(value); }
  144. }
  145. }
  146. }