...

Source file src/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/compile.go

Documentation: github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule

     1  package httprule
     2  
     3  import (
     4  	"github.com/grpc-ecosystem/grpc-gateway/utilities"
     5  )
     6  
     7  const (
     8  	opcodeVersion = 1
     9  )
    10  
    11  // Template is a compiled representation of path templates.
    12  type Template struct {
    13  	// Version is the version number of the format.
    14  	Version int
    15  	// OpCodes is a sequence of operations.
    16  	OpCodes []int
    17  	// Pool is a constant pool
    18  	Pool []string
    19  	// Verb is a VERB part in the template.
    20  	Verb string
    21  	// Fields is a list of field paths bound in this template.
    22  	Fields []string
    23  	// Original template (example: /v1/a_bit_of_everything)
    24  	Template string
    25  }
    26  
    27  // Compiler compiles utilities representation of path templates into marshallable operations.
    28  // They can be unmarshalled by runtime.NewPattern.
    29  type Compiler interface {
    30  	Compile() Template
    31  }
    32  
    33  type op struct {
    34  	// code is the opcode of the operation
    35  	code utilities.OpCode
    36  
    37  	// str is a string operand of the code.
    38  	// num is ignored if str is not empty.
    39  	str string
    40  
    41  	// num is a numeric operand of the code.
    42  	num int
    43  }
    44  
    45  func (w wildcard) compile() []op {
    46  	return []op{
    47  		{code: utilities.OpPush},
    48  	}
    49  }
    50  
    51  func (w deepWildcard) compile() []op {
    52  	return []op{
    53  		{code: utilities.OpPushM},
    54  	}
    55  }
    56  
    57  func (l literal) compile() []op {
    58  	return []op{
    59  		{
    60  			code: utilities.OpLitPush,
    61  			str:  string(l),
    62  		},
    63  	}
    64  }
    65  
    66  func (v variable) compile() []op {
    67  	var ops []op
    68  	for _, s := range v.segments {
    69  		ops = append(ops, s.compile()...)
    70  	}
    71  	ops = append(ops, op{
    72  		code: utilities.OpConcatN,
    73  		num:  len(v.segments),
    74  	}, op{
    75  		code: utilities.OpCapture,
    76  		str:  v.path,
    77  	})
    78  
    79  	return ops
    80  }
    81  
    82  func (t template) Compile() Template {
    83  	var rawOps []op
    84  	for _, s := range t.segments {
    85  		rawOps = append(rawOps, s.compile()...)
    86  	}
    87  
    88  	var (
    89  		ops    []int
    90  		pool   []string
    91  		fields []string
    92  	)
    93  	consts := make(map[string]int)
    94  	for _, op := range rawOps {
    95  		ops = append(ops, int(op.code))
    96  		if op.str == "" {
    97  			ops = append(ops, op.num)
    98  		} else {
    99  			if _, ok := consts[op.str]; !ok {
   100  				consts[op.str] = len(pool)
   101  				pool = append(pool, op.str)
   102  			}
   103  			ops = append(ops, consts[op.str])
   104  		}
   105  		if op.code == utilities.OpCapture {
   106  			fields = append(fields, op.str)
   107  		}
   108  	}
   109  	return Template{
   110  		Version:  opcodeVersion,
   111  		OpCodes:  ops,
   112  		Pool:     pool,
   113  		Verb:     t.verb,
   114  		Fields:   fields,
   115  		Template: t.template,
   116  	}
   117  }
   118  

View as plain text