using System; using System.Collections.Generic; using System.Reflection; using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.DescriptorProtos; namespace Google.ProtocolBuffers.Descriptors { public class FieldDescriptor : IndexedDescriptorBase { private readonly EnumDescriptor enumType; private readonly MessageDescriptor parent; internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, bool isExtension) : base(proto, file, index) { enumType = null; this.parent = parent; } public bool IsRequired { get; set; } public MappedType MappedType { get; set; } public bool IsRepeated { get; set; } public FieldType FieldType { get; set; } public int FieldNumber { get; set; } public bool IsExtension { get; set; } public MessageDescriptor ContainingType { get { return parent; } } public bool IsOptional { get; set; } public MessageDescriptor MessageType { get; set; } public MessageDescriptor ExtensionScope { get; set; } /// /// For enum fields, returns the field's type. /// public EnumDescriptor EnumType { get { if (MappedType != MappedType.Enum) { throw new InvalidOperationException("EnumType is only valid for enum fields."); } return enumType; } } /// /// The default value for this field. For repeated fields /// this will always be an empty list. For message fields it will /// always be null. For singular values, it will depend on the descriptor. /// public object DefaultValue { get { throw new NotImplementedException(); } } /// /// Immutable mapping from field type to mapped type. Built using the attributes on /// FieldType values. /// public static readonly IDictionary FieldTypeToWireFormatMap = MapFieldTypes(); private static IDictionary MapFieldTypes() { var map = new Dictionary(); foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) { FieldType fieldType = (FieldType)field.GetValue(null); FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0]; map[fieldType] = mapping.MappedType; } return Dictionaries.AsReadOnly(map); } } }