LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler - importer.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 7 7 100.0 %
Date: 2015-10-10 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       4             : //
       5             : // Redistribution and use in source and binary forms, with or without
       6             : // modification, are permitted provided that the following conditions are
       7             : // met:
       8             : //
       9             : //     * Redistributions of source code must retain the above copyright
      10             : // notice, this list of conditions and the following disclaimer.
      11             : //     * Redistributions in binary form must reproduce the above
      12             : // copyright notice, this list of conditions and the following disclaimer
      13             : // in the documentation and/or other materials provided with the
      14             : // distribution.
      15             : //     * Neither the name of Google Inc. nor the names of its
      16             : // contributors may be used to endorse or promote products derived from
      17             : // this software without specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      22             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      23             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      24             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      25             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // Author: kenton@google.com (Kenton Varda)
      32             : //  Based on original Protocol Buffers design by
      33             : //  Sanjay Ghemawat, Jeff Dean, and others.
      34             : //
      35             : // This file is the public interface to the .proto file parser.
      36             : 
      37             : #ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
      38             : #define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
      39             : 
      40             : #include <string>
      41             : #include <vector>
      42             : #include <set>
      43             : #include <utility>
      44             : #include <google/protobuf/descriptor.h>
      45             : #include <google/protobuf/descriptor_database.h>
      46             : #include <google/protobuf/compiler/parser.h>
      47             : 
      48             : namespace google {
      49             : namespace protobuf {
      50             : 
      51             : namespace io { class ZeroCopyInputStream; }
      52             : 
      53             : namespace compiler {
      54             : 
      55             : // Defined in this file.
      56             : class Importer;
      57             : class MultiFileErrorCollector;
      58             : class SourceTree;
      59             : class DiskSourceTree;
      60             : 
      61             : // TODO(kenton):  Move all SourceTree stuff to a separate file?
      62             : 
      63             : // An implementation of DescriptorDatabase which loads files from a SourceTree
      64             : // and parses them.
      65             : //
      66             : // Note:  This class is not thread-safe since it maintains a table of source
      67             : //   code locations for error reporting.  However, when a DescriptorPool wraps
      68             : //   a DescriptorDatabase, it uses mutex locking to make sure only one method
      69             : //   of the database is called at a time, even if the DescriptorPool is used
      70             : //   from multiple threads.  Therefore, there is only a problem if you create
      71             : //   multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase
      72             : //   and use them from multiple threads.
      73             : //
      74             : // Note:  This class does not implement FindFileContainingSymbol() or
      75             : //   FindFileContainingExtension(); these will always return false.
      76             : class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase {
      77             :  public:
      78             :   SourceTreeDescriptorDatabase(SourceTree* source_tree);
      79             :   ~SourceTreeDescriptorDatabase();
      80             : 
      81             :   // Instructs the SourceTreeDescriptorDatabase to report any parse errors
      82             :   // to the given MultiFileErrorCollector.  This should be called before
      83             :   // parsing.  error_collector must remain valid until either this method
      84             :   // is called again or the SourceTreeDescriptorDatabase is destroyed.
      85             :   void RecordErrorsTo(MultiFileErrorCollector* error_collector) {
      86          17 :     error_collector_ = error_collector;
      87             :   }
      88             : 
      89             :   // Gets a DescriptorPool::ErrorCollector which records errors to the
      90             :   // MultiFileErrorCollector specified with RecordErrorsTo().  This collector
      91             :   // has the ability to determine exact line and column numbers of errors
      92             :   // from the information given to it by the DescriptorPool.
      93             :   DescriptorPool::ErrorCollector* GetValidationErrorCollector() {
      94          17 :     using_validation_error_collector_ = true;
      95             :     return &validation_error_collector_;
      96             :   }
      97             : 
      98             :   // implements DescriptorDatabase -----------------------------------
      99             :   bool FindFileByName(const string& filename, FileDescriptorProto* output);
     100             :   bool FindFileContainingSymbol(const string& symbol_name,
     101             :                                 FileDescriptorProto* output);
     102             :   bool FindFileContainingExtension(const string& containing_type,
     103             :                                    int field_number,
     104             :                                    FileDescriptorProto* output);
     105             : 
     106             :  private:
     107             :   class SingleFileErrorCollector;
     108             : 
     109             :   SourceTree* source_tree_;
     110             :   MultiFileErrorCollector* error_collector_;
     111             : 
     112             :   class LIBPROTOBUF_EXPORT ValidationErrorCollector : public DescriptorPool::ErrorCollector {
     113             :    public:
     114             :     ValidationErrorCollector(SourceTreeDescriptorDatabase* owner);
     115             :     ~ValidationErrorCollector();
     116             : 
     117             :     // implements ErrorCollector ---------------------------------------
     118             :     void AddError(const string& filename,
     119             :                   const string& element_name,
     120             :                   const Message* descriptor,
     121             :                   ErrorLocation location,
     122             :                   const string& message);
     123             : 
     124             :    private:
     125             :     SourceTreeDescriptorDatabase* owner_;
     126             :   };
     127             :   friend class ValidationErrorCollector;
     128             : 
     129             :   bool using_validation_error_collector_;
     130             :   SourceLocationTable source_locations_;
     131             :   ValidationErrorCollector validation_error_collector_;
     132             : };
     133             : 
     134             : // Simple interface for parsing .proto files.  This wraps the process
     135             : // of opening the file, parsing it with a Parser, recursively parsing all its
     136             : // imports, and then cross-linking the results to produce a FileDescriptor.
     137             : //
     138             : // This is really just a thin wrapper around SourceTreeDescriptorDatabase.
     139             : // You may find that SourceTreeDescriptorDatabase is more flexible.
     140             : //
     141             : // TODO(kenton):  I feel like this class is not well-named.
     142             : class LIBPROTOBUF_EXPORT Importer {
     143             :  public:
     144             :   Importer(SourceTree* source_tree,
     145             :            MultiFileErrorCollector* error_collector);
     146             :   ~Importer();
     147             : 
     148             :   // Import the given file and build a FileDescriptor representing it.  If
     149             :   // the file is already in the DescriptorPool, the existing FileDescriptor
     150             :   // will be returned.  The FileDescriptor is property of the DescriptorPool,
     151             :   // and will remain valid until it is destroyed.  If any errors occur, they
     152             :   // will be reported using the error collector and Import() will return NULL.
     153             :   //
     154             :   // A particular Importer object will only report errors for a particular
     155             :   // file once.  All future attempts to import the same file will return NULL
     156             :   // without reporting any errors.  The idea is that you might want to import
     157             :   // a lot of files without seeing the same errors over and over again.  If
     158             :   // you want to see errors for the same files repeatedly, you can use a
     159             :   // separate Importer object to import each one (but use the same
     160             :   // DescriptorPool so that they can be cross-linked).
     161             :   const FileDescriptor* Import(const string& filename);
     162             : 
     163             :   // The DescriptorPool in which all imported FileDescriptors and their
     164             :   // contents are stored.
     165             :   inline const DescriptorPool* pool() const {
     166             :     return &pool_;
     167             :   }
     168             : 
     169             :   void AddUnusedImportTrackFile(const string& file_name);
     170             :   void ClearUnusedImportTrackFiles();
     171             : 
     172             :  private:
     173             :   SourceTreeDescriptorDatabase database_;
     174             :   DescriptorPool pool_;
     175             : 
     176             :   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer);
     177             : };
     178             : 
     179             : // If the importer encounters problems while trying to import the proto files,
     180             : // it reports them to a MultiFileErrorCollector.
     181             : class LIBPROTOBUF_EXPORT MultiFileErrorCollector {
     182             :  public:
     183          17 :   inline MultiFileErrorCollector() {}
     184             :   virtual ~MultiFileErrorCollector();
     185             : 
     186             :   // Line and column numbers are zero-based.  A line number of -1 indicates
     187             :   // an error with the entire file (e.g. "not found").
     188             :   virtual void AddError(const string& filename, int line, int column,
     189             :                         const string& message) = 0;
     190             : 
     191             :  private:
     192             :   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);
     193             : };
     194             : 
     195             : // Abstract interface which represents a directory tree containing proto files.
     196             : // Used by the default implementation of Importer to resolve import statements
     197             : // Most users will probably want to use the DiskSourceTree implementation,
     198             : // below.
     199             : class LIBPROTOBUF_EXPORT SourceTree {
     200             :  public:
     201          17 :   inline SourceTree() {}
     202             :   virtual ~SourceTree();
     203             : 
     204             :   // Open the given file and return a stream that reads it, or NULL if not
     205             :   // found.  The caller takes ownership of the returned object.  The filename
     206             :   // must be a path relative to the root of the source tree and must not
     207             :   // contain "." or ".." components.
     208             :   virtual io::ZeroCopyInputStream* Open(const string& filename) = 0;
     209             : 
     210             :   // If Open() returns NULL, calling this method immediately will return an
     211             :   // description of the error.
     212             :   // Subclasses should implement this method and return a meaningful value for
     213             :   // better error reporting.
     214             :   // TODO(xiaofeng): change this to a pure virtual function.
     215             :   virtual string GetLastErrorMessage();
     216             : 
     217             :  private:
     218             :   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree);
     219             : };
     220             : 
     221             : // An implementation of SourceTree which loads files from locations on disk.
     222             : // Multiple mappings can be set up to map locations in the DiskSourceTree to
     223             : // locations in the physical filesystem.
     224             : class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree {
     225             :  public:
     226             :   DiskSourceTree();
     227             :   ~DiskSourceTree();
     228             : 
     229             :   // Map a path on disk to a location in the SourceTree.  The path may be
     230             :   // either a file or a directory.  If it is a directory, the entire tree
     231             :   // under it will be mapped to the given virtual location.  To map a directory
     232             :   // to the root of the source tree, pass an empty string for virtual_path.
     233             :   //
     234             :   // If multiple mapped paths apply when opening a file, they will be searched
     235             :   // in order.  For example, if you do:
     236             :   //   MapPath("bar", "foo/bar");
     237             :   //   MapPath("", "baz");
     238             :   // and then you do:
     239             :   //   Open("bar/qux");
     240             :   // the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux,
     241             :   // returning the first one that opens successfuly.
     242             :   //
     243             :   // disk_path may be an absolute path or relative to the current directory,
     244             :   // just like a path you'd pass to open().
     245             :   void MapPath(const string& virtual_path, const string& disk_path);
     246             : 
     247             :   // Return type for DiskFileToVirtualFile().
     248             :   enum DiskFileToVirtualFileResult {
     249             :     SUCCESS,
     250             :     SHADOWED,
     251             :     CANNOT_OPEN,
     252             :     NO_MAPPING
     253             :   };
     254             : 
     255             :   // Given a path to a file on disk, find a virtual path mapping to that
     256             :   // file.  The first mapping created with MapPath() whose disk_path contains
     257             :   // the filename is used.  However, that virtual path may not actually be
     258             :   // usable to open the given file.  Possible return values are:
     259             :   // * SUCCESS: The mapping was found.  *virtual_file is filled in so that
     260             :   //   calling Open(*virtual_file) will open the file named by disk_file.
     261             :   // * SHADOWED: A mapping was found, but using Open() to open this virtual
     262             :   //   path will end up returning some different file.  This is because some
     263             :   //   other mapping with a higher precedence also matches this virtual path
     264             :   //   and maps it to a different file that exists on disk.  *virtual_file
     265             :   //   is filled in as it would be in the SUCCESS case.  *shadowing_disk_file
     266             :   //   is filled in with the disk path of the file which would be opened if
     267             :   //   you were to call Open(*virtual_file).
     268             :   // * CANNOT_OPEN: The mapping was found and was not shadowed, but the
     269             :   //   file specified cannot be opened.  When this value is returned,
     270             :   //   errno will indicate the reason the file cannot be opened.  *virtual_file
     271             :   //   will be set to the virtual path as in the SUCCESS case, even though
     272             :   //   it is not useful.
     273             :   // * NO_MAPPING: Indicates that no mapping was found which contains this
     274             :   //   file.
     275             :   DiskFileToVirtualFileResult
     276             :     DiskFileToVirtualFile(const string& disk_file,
     277             :                           string* virtual_file,
     278             :                           string* shadowing_disk_file);
     279             : 
     280             :   // Given a virtual path, find the path to the file on disk.
     281             :   // Return true and update disk_file with the on-disk path if the file exists.
     282             :   // Return false and leave disk_file untouched if the file doesn't exist.
     283             :   bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file);
     284             : 
     285             :   // implements SourceTree -------------------------------------------
     286             :   virtual io::ZeroCopyInputStream* Open(const string& filename);
     287             : 
     288             :   virtual string GetLastErrorMessage();
     289             : 
     290             :  private:
     291         130 :   struct Mapping {
     292             :     string virtual_path;
     293             :     string disk_path;
     294             : 
     295          18 :     inline Mapping(const string& virtual_path_param,
     296             :                    const string& disk_path_param)
     297          18 :       : virtual_path(virtual_path_param), disk_path(disk_path_param) {}
     298             :   };
     299             :   vector<Mapping> mappings_;
     300             :   string last_error_message_;
     301             : 
     302             :   // Like Open(), but returns the on-disk path in disk_file if disk_file is
     303             :   // non-NULL and the file could be successfully opened.
     304             :   io::ZeroCopyInputStream* OpenVirtualFile(const string& virtual_file,
     305             :                                            string* disk_file);
     306             : 
     307             :   // Like Open() but given the actual on-disk path.
     308             :   io::ZeroCopyInputStream* OpenDiskFile(const string& filename);
     309             : 
     310             :   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree);
     311             : };
     312             : 
     313             : }  // namespace compiler
     314             : }  // namespace protobuf
     315             : 
     316             : }  // namespace google
     317             : #endif  // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__

Generated by: LCOV version 1.10