Exemplo n.º 1
0
        public static PropertyTypeKind DefaultTypeMapper(PropertyDefinition property,
                                                         out TypeDefinition referencedType)
        {
            PropertyTypeKind fieldType = PropertyTypeKind.UNKNOWN;

            // If the property is a reference to another type, this variable contains the typedefinition.
            // Defaults to null.
            referencedType = null;

            // The actual type object of the property.
            TypeReference type = property.PropertyType;

            // The type could be a list<X> (GENERIC), so the actual type would be the first template
            // parameter.
            if (type.IsGenericInstance)
            {
                // We SUPPOSE the actual type is a List with 1 generic parameter.
                type = (type as GenericInstanceType).GenericArguments.First();
            }
            // Get the type by literal name.
            fieldType = LiteralTypeMapper(type.Name);
            if (fieldType == PropertyTypeKind.TYPE_REF)
            {
                // The type is not a primitive and references something else.
                // We just resolve the reference and pass it back.. the caller can
                // decide what to do with it.
                var typeDefinition = type.Resolve();
                referencedType = typeDefinition;
            }

            return(fieldType);
        }
Exemplo n.º 2
0
        // Get all properties from the type we are analyzing.
        public static List <IRClassProperty> ExtractClassProperties(TypeDefinition _subjectClass,
                                                                    out List <TypeDefinition> references)
        {
            // Will contain all typedefinitions of types referenced by this class.
            references = new List <TypeDefinition>();

            // All properties for the given class definition.
            List <IRClassProperty> properties = new List <IRClassProperty>();

            // Property != field
            // Properties expose fields by providing a getter/setter.
            // The properties are public accessible data, and these are the things that map
            // to protobuffer files.
            foreach (var property in _subjectClass.Properties)
            {
                // Property must have a setter method, otherwise it wouldn't be related to ProtoBuffers schema.
                if (property.SetMethod == null)
                {
                    continue;
                }

                // Object which the current property references.
                TypeDefinition refDefinition;
                // Set of field (proto) options.
                IRClassProperty.ILPropertyOptions options = new IRClassProperty.ILPropertyOptions();
                // Default to invalid field.
                options.Label = FieldLabel.INVALID;
                // IR type of the property.
                PropertyTypeKind propType = InspectorTools.DefaultTypeMapper(property, out refDefinition);

                // IR object - reference placeholder for the IR Class.
                IRTypeNode irReference = null;
                if (propType == PropertyTypeKind.TYPE_REF)
                {
                    irReference = InspectorTools.ConstructIRType(refDefinition);
                    // Also save the reference typedefinition for the caller to process.
                    references.Add(refDefinition);
                }

                // Construct IR property and store.
                var prop = new IRClassProperty
                {
                    Name           = property.Name,
                    Type           = propType,
                    ReferencedType = irReference,
                    Options        = options,
                };
                properties.Add(prop);
            }

            return(properties);
        }
Exemplo n.º 3
0
        public static string TypeTostring(PropertyTypeKind type, IRClass current,
                                          IRTypeNode reference)
        {
            switch (type)
            {
            case PropertyTypeKind.DOUBLE:
                return("double");

            case PropertyTypeKind.FLOAT:
                return("float");

            case PropertyTypeKind.INT32:
                return("int32");

            case PropertyTypeKind.INT64:
                return("int64");

            case PropertyTypeKind.UINT32:
                return("uint32");

            case PropertyTypeKind.UINT64:
                return("uint64");

            case PropertyTypeKind.FIXED32:
                return("fixed32");

            case PropertyTypeKind.FIXED64:
                return("fixed64");

            case PropertyTypeKind.BOOL:
                return("bool");

            case PropertyTypeKind.STRING:
                return("string");

            case PropertyTypeKind.BYTES:
                return("bytes");

            case PropertyTypeKind.TYPE_REF:
                return(ResolveTypeReferenceString(current, reference));

            default:
                throw new Exception("Type not recognized!");
            }
        }
Exemplo n.º 4
0
        // Give this function all bytes written to write the header of a field to the wire.
        // It will test if the last 3 bits are value 2. 2 means a length-delimited, =packed,
        // variable.
        // Little ENDIAN order!
        public static bool TagToPackedSpecifier(List <byte> tag, PropertyTypeKind fieldType)
        {
            // Read the last written byte.
            var lastByte = tag.Last();

            // Check if the written bytes are formatted according to the spec.
            if (0 != (lastByte & 0x80))
            {
                throw new InvalidProgramException(
                          "The last byte of the field header must have it's MSB set to 0!");
            }

            // Test if the last 3 bits equal 2 -> = packed | embedded message | string | bytes.
            // ONLY PRIMITIVE TYPES CAN BE PACKED! [varint, 32-bit, or 64-bit wire types]
            if (2 == (lastByte & 0x07) && fieldType < PropertyTypeKind.STRING)
            {
                return(true);
            }

            // Per default, return false.
            return(false);
        }
Exemplo n.º 5
0
        // Get all properties from the type we are analyzing.
        public static List <IRClassProperty> ExtractClassProperties(TypeDefinition _subjectClass,
                                                                    out List <TypeDefinition> references)
        {
            // Contains all references (TypeDefinitions) that are referenced by this class.
            references = new List <TypeDefinition>();

            // All properties for the given class.
            List <IRClassProperty> properties = new List <IRClassProperty>();

            // Propertye != field; see SilentOrbitInspector.ExtractClassproperties(..)
            foreach (var property in _subjectClass.Properties)
            {
                // Default to OPTIONAL label. The Google protobuffer compiler is written for
                // proto3 syntax, which does not allow REQUIRED.
                // Everything is implicitly OPTIONAL, but OPTIONAL fields who have the default value
                // will not be written onto the wire.
                // CARE MUST BE TAKEN to provide all necessary values when using these decompiled proto files.
                FieldLabel label = FieldLabel.OPTIONAL;

                // Each schema related property must have a set method, but repeated fields don't have
                // a set method. We must figure out if the property is lib related or schema related!
                if (property.SetMethod == null)
                {
                    // Repeated field have propertyType RepeatedField<X>.
                    if (property.PropertyType.Name.Contains("RepeatedField") == true &&
                        property.PropertyType.IsGenericInstance)
                    {
                        // This field must be analyzed.
                        label = FieldLabel.REPEATED;
                    }
                    else
                    {
                        continue;
                    }
                }

                // Object which the current property references.
                TypeDefinition refDefinition;
                // Field options (directly related to protobuf schema)
                IRClassProperty.ILPropertyOptions opts = new IRClassProperty.ILPropertyOptions();
                // Add label to the property options.
                opts.Label = label;

                // Fetch the IR type of the property. - Doesn't actually matter, the Serialize handler will overwrite this.
                PropertyTypeKind propType = InspectorTools.DefaultTypeMapper(property, out refDefinition);

                // Construct IR reference placeholder.
                IRTypeNode irReference = null;
                if (propType == PropertyTypeKind.TYPE_REF)
                {
                    irReference = InspectorTools.ConstructIRType(refDefinition);
                    // And save the reference TYPEDEFINITION for the caller to process.
                    references.Add(refDefinition);
                }

                // Fetch the fieldNumber for this property.
                var tag = ExtractFieldNumber(_subjectClass, property.Name);
                // Add it to the options.
                opts.PropertyOrder = tag;

                // Construct the IR property and store it.
                var prop = new IRClassProperty()
                {
                    Name           = property.Name,
                    Type           = propType,
                    ReferencedType = irReference,
                    Options        = opts,
                };
                properties.Add(prop);
            }

            return(properties);
        }