Example #1
0
 /// <summary>
 /// Evaluates the options and returns the qualified name of the umbrella class
 /// relative to the descriptor type's namespace.  Basically concatenates the
 /// UmbrellaNamespace + UmbrellaClassname fields.
 /// </summary>
 internal static string GetQualifiedUmbrellaClassName(CSharpFileOptions options) {
   string fullName = options.UmbrellaClassname;
   if (!options.NestClasses && options.UmbrellaNamespace != "") {
     fullName = String.Format("{0}.{1}", options.UmbrellaNamespace, options.UmbrellaClassname);
   }
   return fullName;
 }
Example #2
0
        private string GetOutputFile(FileDescriptor descriptor)
        {
            CSharpFileOptions fileOptions = descriptor.CSharpOptions;

            string filename = descriptor.CSharpOptions.UmbrellaClassname + descriptor.CSharpOptions.FileExtension;

            string outputDirectory = descriptor.CSharpOptions.OutputDirectory;

            if (fileOptions.ExpandNamespaceDirectories)
            {
                string package = fileOptions.Namespace;
                if (!string.IsNullOrEmpty(package))
                {
                    string[] bits = package.Split('.');
                    foreach (string bit in bits)
                    {
                        outputDirectory = Path.Combine(outputDirectory, bit);
                    }
                }
            }

            // As the directory can be explicitly specified in options, we need to make sure it exists
            Directory.CreateDirectory(outputDirectory);
            return(Path.Combine(outputDirectory, filename));
        }
Example #3
0
        /// <summary>
        /// Evaluates the options and returns the qualified name of the umbrella class
        /// relative to the descriptor type's namespace.  Basically concatenates the
        /// UmbrellaNamespace + UmbrellaClassname fields.
        /// </summary>
        internal static string GetQualifiedUmbrellaClassName(CSharpFileOptions options)
        {
            string fullName = options.UmbrellaClassname;

            if (!options.NestClasses && options.UmbrellaNamespace != "")
            {
                fullName = String.Format("{0}.{1}", options.UmbrellaNamespace, options.UmbrellaClassname);
            }
            return(fullName);
        }
Example #4
0
        internal static string GetFullUmbrellaClassName(IDescriptor descriptor)
        {
            CSharpFileOptions options = descriptor.File.CSharpOptions;
            string            result  = options.Namespace;

            if (result != "")
            {
                result += '.';
            }
            result += GetQualifiedUmbrellaClassName(options);
            return("global::" + result);
        }
Example #5
0
 private CSharpFileOptions BuildOrFakeCSharpOptions()
 {
     // TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues
     if (proto.Name == "google/protobuf/descriptor.proto")
     {
         return(new CSharpFileOptions.Builder {
             Namespace = "Google.ProtocolBuffers.DescriptorProtos",
             UmbrellaClassname = "DescriptorProtoFile", NestClasses = false, MultipleFiles = false, PublicClasses = true
         }.Build());
     }
     if (proto.Name == "google/protobuf/csharp_options.proto")
     {
         return(new CSharpFileOptions.Builder {
             Namespace = "Google.ProtocolBuffers.DescriptorProtos",
             UmbrellaClassname = "CSharpOptions", NestClasses = false, MultipleFiles = false, PublicClasses = true
         }.Build());
     }
     CSharpFileOptions.Builder builder = CSharpFileOptions.CreateBuilder();
     if (proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions))
     {
         builder.MergeFrom(proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
     }
     if (!builder.HasNamespace)
     {
         builder.Namespace = Package;
     }
     if (!builder.HasMultipleFiles)
     {
         builder.MultipleFiles = false;
     }
     if (!builder.HasNestClasses)
     {
         builder.NestClasses = false;
     }
     if (!builder.HasPublicClasses)
     {
         builder.PublicClasses = true;
     }
     if (!builder.HasUmbrellaClassname)
     {
         int    lastSlash = Name.LastIndexOf('/');
         string baseName  = Name.Substring(lastSlash + 1);
         builder.UmbrellaClassname = NameHelpers.UnderscoresToPascalCase(NameHelpers.StripProto(baseName));
     }
     return(builder.Build());
 }
Example #6
0
        private string GetOutputFile(FileDescriptor descriptor, bool duplicates)
        {
            CSharpFileOptions fileOptions = descriptor.CSharpOptions;

            string filename = descriptor.CSharpOptions.UmbrellaClassname + descriptor.CSharpOptions.FileExtension;

            if (duplicates)
            {
                string namepart;
                if (String.IsNullOrEmpty(descriptor.Name) || String.IsNullOrEmpty(namepart = Path.GetFileNameWithoutExtension(descriptor.Name)))
                {
                    throw new ApplicationException("Duplicate UmbrellaClassname options created a file name collision.");
                }

                filename = namepart + descriptor.CSharpOptions.FileExtension;
            }

            string outputDirectory = descriptor.CSharpOptions.OutputDirectory;

            if (fileOptions.ExpandNamespaceDirectories)
            {
                string package = fileOptions.Namespace;
                if (!string.IsNullOrEmpty(package))
                {
                    string[] bits = package.Split('.');
                    foreach (string bit in bits)
                    {
                        outputDirectory = Path.Combine(outputDirectory, bit);
                    }
                }
            }

            // As the directory can be explicitly specified in options, we need to make sure it exists
            Directory.CreateDirectory(outputDirectory);
            return(Path.Combine(outputDirectory, filename));
        }
        /// <summary>
        /// Resolves any dependencies and converts FileDescriptorProtos into FileDescriptors.
        /// The list returned is in the same order as the protos are listed in the descriptor set.
        /// Note: this method is internal rather than private to allow testing.
        /// </summary>
        /// <exception cref="DependencyResolutionException">Not all dependencies could be resolved.</exception>
        internal static IList<FileDescriptor> ConvertDescriptors(CSharpFileOptions options, params FileDescriptorSet[] descriptorProtos)
        {
            // Simple strategy: Keep going through the list of protos to convert, only doing ones where
              // we've already converted all the dependencies, until we get to a stalemate
              List<FileDescriptorProto> fileList = new List<FileDescriptorProto>();
              foreach (FileDescriptorSet set in descriptorProtos)
            fileList.AddRange(set.FileList);

              FileDescriptor[] converted = new FileDescriptor[fileList.Count];

              Dictionary<string, FileDescriptor> convertedMap = new Dictionary<string, FileDescriptor>();

              int totalConverted = 0;

              bool madeProgress = true;
              while (madeProgress && totalConverted < converted.Length) {
            madeProgress = false;
            for (int i = 0; i < converted.Length; i++) {
              if (converted[i] != null) {
            // Already done this one
            continue;
              }
              FileDescriptorProto candidate = fileList[i];
              FileDescriptor[] dependencies = new FileDescriptor[candidate.DependencyList.Count];

              CSharpFileOptions.Builder builder = options.ToBuilder();
              if (candidate.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions)) {
            builder.MergeFrom(candidate.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
              }
              CSharpFileOptions localOptions = builder.Build();

              bool foundAllDependencies = true;
              for (int j = 0; j < dependencies.Length; j++) {
            if (!convertedMap.TryGetValue(candidate.DependencyList[j], out dependencies[j])) {
              // We can auto-magically resolve these since we already have their description
              // This way if the file is only referencing options it does not need to be built with the
              // --include_imports definition.
              if (localOptions.IgnoreGoogleProtobuf && (candidate.DependencyList[j] == "google/protobuf/csharp_options.proto")) {
                dependencies[j] = CSharpOptions.Descriptor;
                continue;
              }
              if (localOptions.IgnoreGoogleProtobuf && (candidate.DependencyList[j] == "google/protobuf/descriptor.proto")) {
                dependencies[j] = DescriptorProtoFile.Descriptor;
                continue;
              }
              foundAllDependencies = false;
              break;
            }
              }
              if (!foundAllDependencies) {
            continue;
              }
              madeProgress = true;
              totalConverted++;
              converted[i] = FileDescriptor.BuildFrom(candidate, dependencies);
              convertedMap[candidate.Name] = converted[i];
            }
              }
              if (!madeProgress) {
            StringBuilder remaining = new StringBuilder();
            for (int i = 0; i < converted.Length; i++) {
              if (converted[i] == null) {
            if (remaining.Length != 0) {
              remaining.Append(", ");
            }
            FileDescriptorProto failure = fileList[i];
            remaining.Append(failure.Name);
            remaining.Append(":");
            foreach (string dependency in failure.DependencyList) {
              if (!convertedMap.ContainsKey(dependency)) {
                remaining.Append(" ");
                remaining.Append(dependency);
              }
            }
            remaining.Append(";");
              }
            }
            throw new DependencyResolutionException("Unable to resolve all dependencies: " + remaining);
              }
              return Lists.AsReadOnly(converted);
        }
Example #8
0
        /// <summary>
        /// Resolves any dependencies and converts FileDescriptorProtos into FileDescriptors.
        /// The list returned is in the same order as the protos are listed in the descriptor set.
        /// Note: this method is internal rather than private to allow testing.
        /// </summary>
        /// <exception cref="DependencyResolutionException">Not all dependencies could be resolved.</exception>
        public static IList <FileDescriptor> ConvertDescriptors(CSharpFileOptions options,
                                                                params FileDescriptorSet[] descriptorProtos)
        {
            // Simple strategy: Keep going through the list of protos to convert, only doing ones where
            // we've already converted all the dependencies, until we get to a stalemate
            List <FileDescriptorProto> fileList = new List <FileDescriptorProto>();

            foreach (FileDescriptorSet set in descriptorProtos)
            {
                fileList.AddRange(set.FileList);
            }

            FileDescriptor[] converted = new FileDescriptor[fileList.Count];

            Dictionary <string, FileDescriptor> convertedMap = new Dictionary <string, FileDescriptor>();

            int totalConverted = 0;

            bool madeProgress = true;

            while (madeProgress && totalConverted < converted.Length)
            {
                madeProgress = false;
                for (int i = 0; i < converted.Length; i++)
                {
                    if (converted[i] != null)
                    {
                        // Already done this one
                        continue;
                    }
                    FileDescriptorProto candidate    = fileList[i];
                    FileDescriptor[]    dependencies = new FileDescriptor[candidate.DependencyList.Count];


                    CSharpFileOptions.Builder builder = options.ToBuilder();
                    if (candidate.Options.HasExtension(CSharpOptions.CSharpFileOptions))
                    {
                        builder.MergeFrom(
                            candidate.Options.GetExtension(CSharpOptions.CSharpFileOptions));
                    }
                    CSharpFileOptions localOptions = builder.Build();

                    bool foundAllDependencies = true;
                    for (int j = 0; j < dependencies.Length; j++)
                    {
                        if (!convertedMap.TryGetValue(candidate.DependencyList[j], out dependencies[j]))
                        {
                            // We can auto-magically resolve these since we already have their description
                            // This way if the file is only referencing options it does not need to be built with the
                            // --include_imports definition.
                            if (localOptions.IgnoreGoogleProtobuf &&
                                (candidate.DependencyList[j] == "google/protobuf/csharp_options.proto"))
                            {
                                dependencies[j] = CSharpOptions.Descriptor;
                                continue;
                            }
                            if (localOptions.IgnoreGoogleProtobuf &&
                                (candidate.DependencyList[j] == "google/protobuf/descriptor.proto"))
                            {
                                dependencies[j] = DescriptorProtoFile.Descriptor;
                                continue;
                            }
                            foundAllDependencies = false;
                            break;
                        }
                    }
                    if (!foundAllDependencies)
                    {
                        continue;
                    }
                    madeProgress = true;
                    totalConverted++;
                    converted[i] = FileDescriptor.BuildFrom(candidate, dependencies);
                    convertedMap[candidate.Name] = converted[i];
                }
            }
            if (!madeProgress)
            {
                StringBuilder remaining = new StringBuilder();
                for (int i = 0; i < converted.Length; i++)
                {
                    if (converted[i] == null)
                    {
                        if (remaining.Length != 0)
                        {
                            remaining.Append(", ");
                        }
                        FileDescriptorProto failure = fileList[i];
                        remaining.Append(failure.Name);
                        remaining.Append(":");
                        foreach (string dependency in failure.DependencyList)
                        {
                            if (!convertedMap.ContainsKey(dependency))
                            {
                                remaining.Append(" ");
                                remaining.Append(dependency);
                            }
                        }
                        remaining.Append(";");
                    }
                }
                throw new DependencyResolutionException("Unable to resolve all dependencies: " + remaining);
            }
            return(Lists.AsReadOnly(converted));
        }
        private CSharpFileOptions BuildOrFakeWithDefaultOptions(CSharpFileOptions defaultOptions)
        {
            // Fix for being able to relocate these files to any directory structure
            if (proto.Package == "google.protobuf")
            {
                string filename = Path.GetFileName(proto.Name);
                // TODO(jonskeet): Check if we could use FileDescriptorProto.Descriptor.Name - interesting bootstrap issues)
                if (filename == "descriptor.proto")
                {
                    return(new CSharpFileOptions.Builder {
                        Namespace = "Google.ProtocolBuffers.DescriptorProtos",
                        UmbrellaClassname = "DescriptorProtoFile",
                        NestClasses = false,
                        MultipleFiles = false,
                        PublicClasses = true,
                        OutputDirectory = defaultOptions.OutputDirectory,
                        IgnoreGoogleProtobuf = defaultOptions.IgnoreGoogleProtobuf
                    }.Build());
                }
                if (filename == "csharp_options.proto")
                {
                    return(new CSharpFileOptions.Builder {
                        Namespace = "Google.ProtocolBuffers.DescriptorProtos",
                        UmbrellaClassname = "CSharpOptions",
                        NestClasses = false,
                        MultipleFiles = false,
                        PublicClasses = true,
                        OutputDirectory = defaultOptions.OutputDirectory,
                        IgnoreGoogleProtobuf = defaultOptions.IgnoreGoogleProtobuf
                    }.Build());
                }
            }
            CSharpFileOptions.Builder builder = defaultOptions.ToBuilder();
            if (proto.Options.HasExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions))
            {
                builder.MergeFrom(proto.Options.GetExtension(DescriptorProtos.CSharpOptions.CSharpFileOptions));
            }
            if (!builder.HasNamespace)
            {
                builder.Namespace = Package;
            }
            if (!builder.HasUmbrellaClassname)
            {
                int    lastSlash = Name.LastIndexOf('/');
                string baseName  = Name.Substring(lastSlash + 1);
                builder.UmbrellaClassname = NameHelpers.UnderscoresToPascalCase(NameHelpers.StripProto(baseName));
            }

            // Auto-fix for name collision by placing umbrella class into a new namespace.  This
            // still won't fix the collisions with nesting enabled; however, you have to turn that on explicitly anyway.
            if (!builder.NestClasses && !builder.HasUmbrellaNamespace)
            {
                bool collision = false;
                foreach (IDescriptor d in MessageTypes)
                {
                    collision |= d.Name == builder.UmbrellaClassname;
                }
                foreach (IDescriptor d in Services)
                {
                    collision |= d.Name == builder.UmbrellaClassname;
                }
                foreach (IDescriptor d in EnumTypes)
                {
                    collision |= d.Name == builder.UmbrellaClassname;
                }
                if (collision)
                {
                    builder.UmbrellaNamespace = "Proto";
                }
            }

            return(builder.Build());
        }
 /// <summary>
 /// Allows a file descriptor to be configured with a set of external options, e.g. from the
 /// command-line arguments to protogen.
 /// </summary>
 public void ConfigureWithDefaultOptions(CSharpFileOptions options)
 {
     csharpFileOptions = BuildOrFakeWithDefaultOptions(options);
 }