GeneratedExtension.cs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using Google.ProtocolBuffers.Descriptors;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. namespace Google.ProtocolBuffers {
  6. public static class GeneratedExtension {
  7. public static GeneratedExtension<TContainer, TExtension> CreateExtension<TContainer, TExtension>(FieldDescriptor descriptor)
  8. where TContainer : IMessage<TContainer> {
  9. if (descriptor.IsRepeated) {
  10. throw new ArgumentException("Must call CreateRepeatedGeneratedExtension() for repeated types.");
  11. }
  12. return new GeneratedExtension<TContainer, TExtension>(descriptor);
  13. }
  14. public static GeneratedExtension<TContainer, IList<TExtension>> CreateRepeatedExtension<TContainer, TExtension>(FieldDescriptor descriptor)
  15. where TContainer : IMessage<TContainer> {
  16. if (descriptor.IsRepeated) {
  17. throw new ArgumentException("Must call CreateRepeatedGeneratedExtension() for repeated types.");
  18. }
  19. return new GeneratedExtension<TContainer, IList<TExtension>>(descriptor);
  20. }
  21. }
  22. /// <summary>
  23. /// Base class for all generated extensions.
  24. /// </summary>
  25. /// <remarks>
  26. /// The protocol compiler generates a static singleton instance of this
  27. /// class for each extension. For exmaple, imagine a .proto file with:
  28. /// <code>
  29. /// message Foo {
  30. /// extensions 1000 to max
  31. /// }
  32. ///
  33. /// extend Foo {
  34. /// optional int32 bar;
  35. /// }
  36. /// </code>
  37. /// Then MyProto.Foo.Bar has type GeneratedExtension&lt;MyProto.Foo,int&gt;.
  38. /// <para />
  39. /// In general, users should ignore the details of this type, and
  40. /// simply use the static singletons as parmaeters to the extension accessors
  41. /// in ExtendableMessage and ExtendableBuilder.
  42. /// </remarks>
  43. public class GeneratedExtension<TContainer, TExtension> where TContainer : IMessage<TContainer> {
  44. private readonly IMessage messageDefaultInstance;
  45. private readonly FieldDescriptor descriptor;
  46. internal GeneratedExtension(FieldDescriptor descriptor) {
  47. if (!descriptor.IsExtension) {
  48. throw new ArgumentException("GeneratedExtension given a regular (non-extension) field.");
  49. }
  50. this.descriptor = descriptor;
  51. switch (descriptor.MappedType) {
  52. case MappedType.Message:
  53. PropertyInfo defaultInstanceProperty = typeof(TExtension)
  54. .GetProperty("DefaultInstance", BindingFlags.Static | BindingFlags.Public);
  55. if (defaultInstanceProperty == null) {
  56. throw new ArgumentException("No public static DefaultInstance property for type " + typeof(TExtension).Name);
  57. }
  58. messageDefaultInstance = (IMessage) defaultInstanceProperty.GetValue(null, null);
  59. break;
  60. case MappedType.Enum:
  61. // FIXME(jonskeet): May not need this
  62. //enumValueOf = getMethodOrDie(type, "valueOf",
  63. // EnumValueDescriptor.class);
  64. //enumGetValueDescriptor = getMethodOrDie(type, "getValueDescriptor");
  65. messageDefaultInstance = null;
  66. break;
  67. default:
  68. messageDefaultInstance = null;
  69. break;
  70. }
  71. }
  72. public FieldDescriptor Descriptor {
  73. get { return descriptor; }
  74. }
  75. public IMessage MessageDefaultInstance {
  76. get { return messageDefaultInstance; }
  77. }
  78. internal object SingularFromReflectionType(object p) {
  79. throw new System.NotImplementedException();
  80. }
  81. internal object FromReflectionType(object value) {
  82. throw new System.NotImplementedException();
  83. }
  84. }
  85. }