internal/protobuf: add proto definition extraction

Change-Id: Ia356bcb951e30bcc8030b51cbc5d9949391e84dc
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/1980
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/internal/protobuf/testdata/attributes.proto.out.cue b/internal/protobuf/testdata/attributes.proto.out.cue
new file mode 100644
index 0000000..73f70ad
--- /dev/null
+++ b/internal/protobuf/testdata/attributes.proto.out.cue
@@ -0,0 +1,136 @@
+
+//  Copyright 2016 Istio Authors
+// 
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+// 
+//      http://www.apache.org/licenses/LICENSE-2.0
+// 
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+package v1
+
+import "time"
+
+//  Attributes represents a set of typed name/value pairs. Many of Mixer's
+//  API either consume and/or return attributes.
+// 
+//  Istio uses attributes to control the runtime behavior of services running in the service mesh.
+//  Attributes are named and typed pieces of metadata describing ingress and egress traffic and the
+//  environment this traffic occurs in. An Istio attribute carries a specific piece
+//  of information such as the error code of an API request, the latency of an API request, or the
+//  original IP address of a TCP connection. For example:
+// 
+//  ```yaml
+//  request.path: xyz/abc
+//  request.size: 234
+//  request.time: 12:34:56.789 04/17/2017
+//  source.ip: 192.168.0.1
+//  target.service: example
+//  ```
+// 
+//  A given Istio deployment has a fixed vocabulary of attributes that it understands.
+//  The specific vocabulary is determined by the set of attribute producers being used
+//  in the deployment. The primary attribute producer in Istio is Envoy, although
+//  specialized Mixer adapters and services can also generate attributes.
+// 
+//  The common baseline set of attributes available in most Istio deployments is defined
+//  [here](https://istio.io/docs/reference/config/policy-and-telemetry/attribute-vocabulary/).
+// 
+//  Attributes are strongly typed. The supported attribute types are defined by
+//  [ValueType](https://github.com/istio/api/blob/master/policy/v1beta1/value_type.proto).
+//  Each type of value is encoded into one of the so-called transport types present
+//  in this message.
+// 
+//  Defines a map of attributes in uncompressed format.
+//  Following places may use this message:
+//  1) Configure Istio/Proxy with static per-proxy attributes, such as source.uid.
+//  2) Service IDL definition to extract api attributes for active requests.
+//  3) Forward attributes from client proxy to server proxy for HTTP requests.
+Attributes: {
+	//  A map of attribute name to its value.
+	attributes <_>: Attributes_AttributeValue
+}
+
+//  Specifies one attribute value with different type.
+Attributes_AttributeValue: {
+}
+//  The attribute value.
+Attributes_AttributeValue: {
+	//  Used for values of type STRING, DNS_NAME, EMAIL_ADDRESS, and URI
+	stringValue: string @protobuf(2,name=string_value)
+} | {
+	//  Used for values of type INT64
+	int64Value: int64 @protobuf(3,name=int64_value)
+} | {
+	//  Used for values of type DOUBLE
+	doubleValue: float64 @protobuf(4,type=double,name=double_value)
+} | {
+	//  Used for values of type BOOL
+	boolValue: bool @protobuf(5,name=bool_value)
+} | {
+	//  Used for values of type BYTES
+	bytesValue: bytes @protobuf(6,name=bytes_value)
+} | {
+	//  Used for values of type TIMESTAMP
+	timestampValue: time.Time @protobuf(7,type=google.protobuf.Timestamp,name=timestamp_value)
+} | {
+	//  Used for values of type DURATION
+	durationValue: time.Duration @protobuf(8,type=google.protobuf.Duration,name=duration_value)
+} | {
+	//  Used for values of type STRING_MAP
+	stringMapValue: Attributes_StringMap @protobuf(9,type=StringMap,name=string_map_value)
+}
+
+//  Defines a string map.
+Attributes_StringMap: {
+	//  Holds a set of name/value pairs.
+	entries <_>: string
+}
+
+//  Defines a list of attributes in compressed format optimized for transport.
+//  Within this message, strings are referenced using integer indices into
+//  one of two string dictionaries. Positive integers index into the global
+//  deployment-wide dictionary, whereas negative integers index into the message-level
+//  dictionary instead. The message-level dictionary is carried by the
+//  `words` field of this message, the deployment-wide dictionary is determined via
+//  configuration.
+CompressedAttributes: {
+	//  The message-level dictionary.
+	words?: [...string] @protobuf(1)
+
+	//  Holds attributes of type STRING, DNS_NAME, EMAIL_ADDRESS, URI
+	strings <_>: int32
+
+	//  Holds attributes of type INT64
+	int64s <_>: int64
+
+	//  Holds attributes of type DOUBLE
+	doubles <_>: float64
+
+	//  Holds attributes of type BOOL
+	bools <_>: bool
+
+	//  Holds attributes of type TIMESTAMP
+	timestamps <_>: time.Time
+
+	//  Holds attributes of type DURATION
+	durations <_>: time.Duration
+
+	//  Holds attributes of type BYTES
+	bytes <_>: bytes
+
+	//  Holds attributes of type STRING_MAP
+	stringMaps <_>: StringMap
+}
+
+//  A map of string to string. The keys and values in this map are dictionary
+//  indices (see the [Attributes][istio.mixer.v1.CompressedAttributes] message for an explanation)
+StringMap: {
+	//  Holds a set of name/value pairs.
+	entries <_>: int32
+}
diff --git a/internal/protobuf/testdata/client_config.proto.out.cue b/internal/protobuf/testdata/client_config.proto.out.cue
new file mode 100644
index 0000000..880309e
--- /dev/null
+++ b/internal/protobuf/testdata/client_config.proto.out.cue
@@ -0,0 +1,193 @@
+
+//  Copyright 2017 Istio Authors
+// 
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+// 
+//        http://www.apache.org/licenses/LICENSE-2.0
+// 
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+//  $title: Mixer Client
+//  $description: Configuration state for the Mixer client library.
+//  $location: https://istio.io/docs/reference/config/policy-and-telemetry/istio.mixer.v1.config.client
+
+//  Describes the configuration state for the Mixer client library that's built into Envoy.
+package client
+
+import (
+	"istio.io/api/mixer/v1"
+	"time"
+)
+
+//  Specifies the behavior when the client is unable to connect to Mixer.
+NetworkFailPolicy: {
+
+	//  Specifies the behavior when the client is unable to connect to Mixer.
+	policy?: NetworkFailPolicy_FailPolicy @protobuf(1,type=FailPolicy)
+
+	//  Max retries on transport error.
+	maxRetry?: uint32 @protobuf(2,name=max_retry)
+
+	//  Base time to wait between retries.  Will be adjusted by exponential
+	//  backoff and jitter.
+	baseRetryWait?: time.Duration @protobuf(3,type=google.protobuf.Duration,name=base_retry_wait)
+
+	//  Max time to wait between retries.
+	maxRetryWait?: time.Duration @protobuf(4,type=google.protobuf.Duration,name=max_retry_wait)
+}
+
+//  Describes the policy.
+NetworkFailPolicy_FailPolicy:
+	//  If network connection fails, request is allowed and delivered to the
+	//  service.
+	*"FAIL_OPEN" |
+
+	//  If network connection fails, request is rejected.
+	"FAIL_CLOSE"
+
+NetworkFailPolicy_FailPolicy_value: {
+	"FAIL_OPEN":  0
+	"FAIL_CLOSE": 1
+}
+
+//  Defines the per-service client configuration.
+ServiceConfig: {
+	//  If true, do not call Mixer Check.
+	disableCheckCalls?: bool @protobuf(1,name=disable_check_calls)
+
+	//  If true, do not call Mixer Report.
+	disableReportCalls?: bool @protobuf(2,name=disable_report_calls)
+
+	//  Send these attributes to Mixer in both Check and Report. This
+	//  typically includes the "destination.service" attribute.
+	//  In case of a per-route override, per-route attributes take precedence
+	//  over the attributes supplied in the client configuration.
+	mixerAttributes?: v1.Attributes @protobuf(3,type=Attributes,name=mixer_attributes)
+
+	//  HTTP API specifications to generate API attributes.
+	httpApiSpec?: [...HTTPAPISpec] @protobuf(4,name=http_api_spec)
+
+	//  Quota specifications to generate quota requirements.
+	quotaSpec?: [...QuotaSpec] @protobuf(5,name=quota_spec)
+
+	//  Specifies the behavior when the client is unable to connect to Mixer.
+	//  This is the service-level policy. It overrides
+	//  [mesh-level
+	//  policy][istio.mixer.v1.config.client.TransportConfig.network_fail_policy].
+	networkFailPolicy?: NetworkFailPolicy @protobuf(7,name=network_fail_policy)
+
+	//  Default attributes to forward to upstream. This typically
+	//  includes the "source.ip" and "source.uid" attributes.
+	//  In case of a per-route override, per-route attributes take precedence
+	//  over the attributes supplied in the client configuration.
+	// 
+	//  Forwarded attributes take precedence over the static Mixer attributes.
+	//  The full order of application is as follows:
+	//  1. static Mixer attributes from the filter config;
+	//  2. static Mixer attributes from the route config;
+	//  3. forwarded attributes from the source filter config (if any);
+	//  4. forwarded attributes from the source route config (if any);
+	//  5. derived attributes from the request metadata.
+	forwardAttributes?: v1.Attributes @protobuf(8,type=Attributes,name=forward_attributes)
+}
+
+//  Defines the transport config on how to call Mixer.
+TransportConfig: {
+	//  The flag to disable check cache.
+	disableCheckCache?: bool @protobuf(1,name=disable_check_cache)
+
+	//  The flag to disable quota cache.
+	disableQuotaCache?: bool @protobuf(2,name=disable_quota_cache)
+
+	//  The flag to disable report batch.
+	disableReportBatch?: bool @protobuf(3,name=disable_report_batch)
+
+	//  Specifies the behavior when the client is unable to connect to Mixer.
+	//  This is the mesh level policy. The default value for policy is FAIL_OPEN.
+	networkFailPolicy?: NetworkFailPolicy @protobuf(4,name=network_fail_policy)
+
+	//  Specify refresh interval to write Mixer client statistics to Envoy share
+	//  memory. If not specified, the interval is 10 seconds.
+	statsUpdateInterval?: time.Duration @protobuf(5,type=google.protobuf.Duration,name=stats_update_interval)
+
+	//  Name of the cluster that will forward check calls to a pool of mixer
+	//  servers. Defaults to "mixer_server". By using different names for
+	//  checkCluster and reportCluster, it is possible to have one set of
+	//  Mixer servers handle check calls, while another set of Mixer servers
+	//  handle report calls.
+	// 
+	//  NOTE: Any value other than the default "mixer_server" will require the
+	//  Istio Grafana dashboards to be reconfigured to use the new name.
+	checkCluster?: string @protobuf(6,name=check_cluster)
+
+	//  Name of the cluster that will forward report calls to a pool of mixer
+	//  servers. Defaults to "mixer_server". By using different names for
+	//  checkCluster and reportCluster, it is possible to have one set of
+	//  Mixer servers handle check calls, while another set of Mixer servers
+	//  handle report calls.
+	// 
+	//  NOTE: Any value other than the default "mixer_server" will require the
+	//  Istio Grafana dashboards to be reconfigured to use the new name.
+	reportCluster?: string @protobuf(7,name=report_cluster)
+
+	//  Default attributes to forward to Mixer upstream. This typically
+	//  includes the "source.ip" and "source.uid" attributes. These
+	//  attributes are consumed by the proxy in front of mixer.
+	attributesForMixerProxy?: v1.Attributes @protobuf(8,type=Attributes,name=attributes_for_mixer_proxy)
+}
+
+//  Defines the client config for HTTP.
+HttpClientConfig: {
+	//  The transport config.
+	transport?: TransportConfig @protobuf(1)
+
+	//  Map of control configuration indexed by destination.service. This
+	//  is used to support per-service configuration for cases where a
+	//  mixerclient serves multiple services.
+	serviceConfigs <_>: ServiceConfig
+
+	//  Default destination service name if none was specified in the
+	//  client request.
+	defaultDestinationService?: string @protobuf(3,name=default_destination_service)
+
+	//  Default attributes to send to Mixer in both Check and
+	//  Report. This typically includes "destination.ip" and
+	//  "destination.uid" attributes.
+	mixerAttributes?: v1.Attributes @protobuf(4,type=Attributes,name=mixer_attributes)
+
+	//  Default attributes to forward to upstream. This typically
+	//  includes the "source.ip" and "source.uid" attributes.
+	forwardAttributes?: v1.Attributes @protobuf(5,type=Attributes,name=forward_attributes)
+}
+
+//  Defines the client config for TCP.
+TcpClientConfig: {
+	//  The transport config.
+	transport?: TransportConfig @protobuf(1)
+
+	//  Default attributes to send to Mixer in both Check and
+	//  Report. This typically includes "destination.ip" and
+	//  "destination.uid" attributes.
+	mixerAttributes?: v1.Attributes @protobuf(2,type=Attributes,name=mixer_attributes)
+
+	//  If set to true, disables Mixer check calls.
+	disableCheckCalls?: bool @protobuf(3,name=disable_check_calls)
+
+	//  If set to true, disables Mixer check calls.
+	disableReportCalls?: bool @protobuf(4,name=disable_report_calls)
+
+	//  Quota specifications to generate quota requirements.
+	//  It applies on the new TCP connections.
+	connectionQuotaSpec?: QuotaSpec @protobuf(5,name=connection_quota_spec)
+
+	//  Specify report interval to send periodical reports for long TCP
+	//  connections. If not specified, the interval is 10 seconds. This interval
+	//  should not be less than 1 second, otherwise it will be reset to 1 second.
+	reportInterval?: time.Duration @protobuf(6,type=google.protobuf.Duration,name=report_interval)
+}
diff --git a/internal/protobuf/testdata/cue.proto b/internal/protobuf/testdata/cue.proto
new file mode 100644
index 0000000..4bbb948
--- /dev/null
+++ b/internal/protobuf/testdata/cue.proto
@@ -0,0 +1,18 @@
+syntax = "proto3";
+
+package cue;
+
+import "google/protobuf/descriptor.proto";
+
+option go_package = "cuelang.org/cueproto";
+option java_package = "org.cuelang.cueproto";
+
+message FieldOptions {
+    bool required = 1;
+}
+
+extend google.protobuf.FieldOptions {
+    string val = 123456;
+    FieldOptions opt = 1069;
+}
+
diff --git a/internal/protobuf/testdata/cue.proto.out.cue b/internal/protobuf/testdata/cue.proto.out.cue
new file mode 100644
index 0000000..3a46082
--- /dev/null
+++ b/internal/protobuf/testdata/cue.proto.out.cue
@@ -0,0 +1,8 @@
+package proto
+
+FieldOptions required?: bool @protobuf(1)
+
+google.protobuf.FieldOptions: {
+	val?: string       @protobuf(123456)
+	opt?: FieldOptions @protobuf(1069)
+}
diff --git a/internal/protobuf/testdata/gateway.proto.out.cue b/internal/protobuf/testdata/gateway.proto.out.cue
new file mode 100644
index 0000000..14e4624
--- /dev/null
+++ b/internal/protobuf/testdata/gateway.proto.out.cue
@@ -0,0 +1,451 @@
+
+//  Copyright 2019 CUE Authors
+// 
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//  
+//      http://www.apache.org/licenses/LICENSE-2.0
+//  
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+
+//  Copyright 2017 Istio Authors
+// 
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+// 
+//        http://www.apache.org/licenses/LICENSE-2.0
+// 
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+//  $title: Gateway
+//  $description: Configuration affecting edge load balancer.
+//  $location: https://istio.io/docs/reference/config/networking/v1alpha3/gateway.html
+
+//  `Gateway` describes a load balancer operating at the edge of the mesh
+//  receiving incoming or outgoing HTTP/TCP connections. The specification
+//  describes a set of ports that should be exposed, the type of protocol to
+//  use, SNI configuration for the load balancer, etc.
+// 
+//  For example, the following Gateway configuration sets up a proxy to act
+//  as a load balancer exposing port 80 and 9080 (http), 443 (https),
+//  9443(https) and port 2379 (TCP) for ingress.  The gateway will be
+//  applied to the proxy running on a pod with labels `app:
+//  my-gateway-controller`. While Istio will configure the proxy to listen
+//  on these ports, it is the responsibility of the user to ensure that
+//  external traffic to these ports are allowed into the mesh.
+// 
+//  ```yaml
+//  apiVersion: networking.istio.io/v1alpha3
+//  kind: Gateway
+//  metadata:
+//    name: my-gateway
+//    namespace: some-config-namespace
+//  spec:
+//    selector:
+//      app: my-gateway-controller
+//    servers:
+//    - port:
+//        number: 80
+//        name: http
+//        protocol: HTTP
+//      hosts:
+//      - uk.bookinfo.com
+//      - eu.bookinfo.com
+//      tls:
+//        httpsRedirect: true # sends 301 redirect for http requests
+//    - port:
+//        number: 443
+//        name: https-443
+//        protocol: HTTPS
+//      hosts:
+//      - uk.bookinfo.com
+//      - eu.bookinfo.com
+//      tls:
+//        mode: SIMPLE # enables HTTPS on this port
+//        serverCertificate: /etc/certs/servercert.pem
+//        privateKey: /etc/certs/privatekey.pem
+//    - port:
+//        number: 9443
+//        name: https-9443
+//        protocol: HTTPS
+//      hosts:
+//      - "bookinfo-namespace/*.bookinfo.com"
+//      tls:
+//        mode: SIMPLE # enables HTTPS on this port
+//        credentialName: bookinfo-secret # fetches certs from Kubernetes secret
+//    - port:
+//        number: 9080
+//        name: http-wildcard
+//        protocol: HTTP
+//      hosts:
+//      - "*"
+//    - port:
+//        number: 2379 # to expose internal service via external port 2379
+//        name: mongo
+//        protocol: MONGO
+//      hosts:
+//      - "*"
+//  ```
+// 
+//  The Gateway specification above describes the L4-L6 properties of a load
+//  balancer. A `VirtualService` can then be bound to a gateway to control
+//  the forwarding of traffic arriving at a particular host or gateway port.
+// 
+//  For example, the following VirtualService splits traffic for
+//  `https://uk.bookinfo.com/reviews`, `https://eu.bookinfo.com/reviews`,
+//  `http://uk.bookinfo.com:9080/reviews`,
+//  `http://eu.bookinfo.com:9080/reviews` into two versions (prod and qa) of
+//  an internal reviews service on port 9080. In addition, requests
+//  containing the cookie "user: dev-123" will be sent to special port 7777
+//  in the qa version. The same rule is also applicable inside the mesh for
+//  requests to the "reviews.prod.svc.cluster.local" service. This rule is
+//  applicable across ports 443, 9080. Note that `http://uk.bookinfo.com`
+//  gets redirected to `https://uk.bookinfo.com` (i.e. 80 redirects to 443).
+// 
+//  ```yaml
+//  apiVersion: networking.istio.io/v1alpha3
+//  kind: VirtualService
+//  metadata:
+//    name: bookinfo-rule
+//    namespace: bookinfo-namespace
+//  spec:
+//    hosts:
+//    - reviews.prod.svc.cluster.local
+//    - uk.bookinfo.com
+//    - eu.bookinfo.com
+//    gateways:
+//    - some-config-namespace/my-gateway
+//    - mesh # applies to all the sidecars in the mesh
+//    http:
+//    - match:
+//      - headers:
+//          cookie:
+//            exact: "user=dev-123"
+//      route:
+//      - destination:
+//          port:
+//            number: 7777
+//          host: reviews.qa.svc.cluster.local
+//    - match:
+//      - uri:
+//          prefix: /reviews/
+//      route:
+//      - destination:
+//          port:
+//            number: 9080 # can be omitted if it's the only port for reviews
+//          host: reviews.prod.svc.cluster.local
+//        weight: 80
+//      - destination:
+//          host: reviews.qa.svc.cluster.local
+//        weight: 20
+//  ```
+// 
+//  The following VirtualService forwards traffic arriving at (external)
+//  port 27017 to internal Mongo server on port 5555. This rule is not
+//  applicable internally in the mesh as the gateway list omits the
+//  reserved name `mesh`.
+// 
+//  ```yaml
+//  apiVersion: networking.istio.io/v1alpha3
+//  kind: VirtualService
+//  metadata:
+//    name: bookinfo-Mongo
+//    namespace: bookinfo-namespace
+//  spec:
+//    hosts:
+//    - mongosvr.prod.svc.cluster.local # name of internal Mongo service
+//    gateways:
+//    - some-config-namespace/my-gateway # can omit the namespace if gateway is in same
+//                                         namespace as virtual service.
+//    tcp:
+//    - match:
+//      - port: 27017
+//      route:
+//      - destination:
+//          host: mongo.prod.svc.cluster.local
+//          port:
+//            number: 5555
+//  ```
+// 
+//  It is possible to restrict the set of virtual services that can bind to
+//  a gateway server using the namespace/hostname syntax in the hosts field.
+//  For example, the following Gateway allows any virtual service in the ns1
+//  namespace to bind to it, while restricting only the virtual service with
+//  foo.bar.com host in the ns2 namespace to bind to it.
+// 
+//  ```yaml
+//  apiVersion: networking.istio.io/v1alpha3
+//  kind: Gateway
+//  metadata:
+//    name: my-gateway
+//    namespace: some-config-namespace
+//  spec:
+//    selector:
+//      app: my-gateway-controller
+//    servers:
+//    - port:
+//        number: 80
+//        name: http
+//        protocol: HTTP
+//      hosts:
+//      - "ns1/*"
+//      - "ns2/foo.bar.com"
+//  ```
+// 
+package v1alpha3
+
+Gateway: {
+	//  REQUIRED: A list of server specifications.
+	servers?: [...Server] @protobuf(1)
+
+	//  REQUIRED: One or more labels that indicate a specific set of pods/VMs
+	//  on which this gateway configuration should be applied. The scope of
+	//  label search is restricted to the configuration namespace in which the
+	//  the resource is present. In other words, the Gateway resource must
+	//  reside in the same namespace as the gateway workload instance.
+	selector <_>: string
+	selector?: {<name>: name}
+}
+
+//  `Server` describes the properties of the proxy on a given load balancer
+//  port. For example,
+// 
+//  ```yaml
+//  apiVersion: networking.istio.io/v1alpha3
+//  kind: Gateway
+//  metadata:
+//    name: my-ingress
+//  spec:
+//    selector:
+//      app: my-ingress-gateway
+//    servers:
+//    - port:
+//        number: 80
+//        name: http2
+//        protocol: HTTP2
+//      hosts:
+//      - "*"
+//  ```
+// 
+//  Another example
+// 
+//  ```yaml
+//  apiVersion: networking.istio.io/v1alpha3
+//  kind: Gateway
+//  metadata:
+//    name: my-tcp-ingress
+//  spec:
+//    selector:
+//      app: my-tcp-ingress-gateway
+//    servers:
+//    - port:
+//        number: 27018
+//        name: mongo
+//        protocol: MONGO
+//      hosts:
+//      - "*"
+//  ```
+// 
+//  The following is an example of TLS configuration for port 443
+// 
+//  ```yaml
+//  apiVersion: networking.istio.io/v1alpha3
+//  kind: Gateway
+//  metadata:
+//    name: my-tls-ingress
+//  spec:
+//    selector:
+//      app: my-tls-ingress-gateway
+//    servers:
+//    - port:
+//        number: 443
+//        name: https
+//        protocol: HTTPS
+//      hosts:
+//      - "*"
+//      tls:
+//        mode: SIMPLE
+//        serverCertificate: /etc/certs/server.pem
+//        privateKey: /etc/certs/privatekey.pem
+//  ```
+Server: {
+	//  REQUIRED: The Port on which the proxy should listen for incoming
+	//  connections.
+	port?: Port @protobuf(1)
+	port?: >10 & <100
+
+	//  $hide_from_docs
+	//  The ip or the Unix domain socket to which the listener should be bound
+	//  to. Format: `x.x.x.x` or `unix:///path/to/uds` or `unix://@foobar`
+	//  (Linux abstract namespace). When using Unix domain sockets, the port
+	//  number should be 0.
+	bind?: string @protobuf(4)
+
+	//  REQUIRED. One or more hosts exposed by this gateway.
+	//  While typically applicable to
+	//  HTTP services, it can also be used for TCP services using TLS with SNI.
+	//  A host is specified as a `dnsName` with an optional `namespace/` prefix.
+	//  The `dnsName` should be specified using FQDN format, optionally including
+	//  a wildcard character in the left-most component (e.g., `prod/*.example.com`).
+	//  Set the `dnsName` to `*` to select all `VirtualService` hosts from the
+	//  specified namespace (e.g.,`prod/*`). If no `namespace/` is specified,
+	//  the `VirtualService` hosts will be selected from any available namespace.
+	//  Any associated `DestinationRule` in the same namespace will also be used.
+	// 
+	//  A `VirtualService` must be bound to the gateway and must have one or
+	//  more hosts that match the hosts specified in a server. The match
+	//  could be an exact match or a suffix match with the server's hosts. For
+	//  example, if the server's hosts specifies `*.example.com`, a
+	//  `VirtualService` with hosts `dev.example.com` or `prod.example.com` will
+	//  match. However, a `VirtualService` with host `example.com` or
+	//  `newexample.com` will not match.
+	// 
+	//  NOTE: Only virtual services exported to the gateway's namespace
+	//  (e.g., `exportTo` value of `*`) can be referenced.
+	//  Private configurations (e.g., `exportTo` set to `.`) will not be
+	//  available. Refer to the `exportTo` setting in `VirtualService`,
+	//  `DestinationRule`, and `ServiceEntry` configurations for details.
+	hosts?: [...string] @protobuf(2)
+
+	//  Set of TLS related options that govern the server's behavior. Use
+	//  these options to control if all http requests should be redirected to
+	//  https, and the TLS modes to use.
+	tls?: Server_TLSOptions @protobuf(3,type=TLSOptions)
+
+	//  The loopback IP endpoint or Unix domain socket to which traffic should
+	//  be forwarded to by default. Format should be `127.0.0.1:PORT` or
+	//  `unix:///path/to/socket` or `unix://@foobar` (Linux abstract namespace).
+	defaultEndpoint?: string @protobuf(5,name=default_endpoint)
+}
+
+Server_TLSOptions: {
+	//  If set to true, the load balancer will send a 301 redirect for all
+	//  http connections, asking the clients to use HTTPS.
+	httpsRedirect?: bool @protobuf(1,name=https_redirect)
+
+	//  Optional: Indicates whether connections to this port should be
+	//  secured using TLS. The value of this field determines how TLS is
+	//  enforced.
+	mode?: Server_TLSOptions_TLSmode @protobuf(2,type=TLSmode)
+
+	//  Extra comment.
+
+	//  REQUIRED if mode is `SIMPLE` or `MUTUAL`. The path to the file
+	//  holding the server-side TLS certificate to use.
+	serverCertificate?: string @protobuf(3,name=server_certificate)
+
+	//  REQUIRED if mode is `SIMPLE` or `MUTUAL`. The path to the file
+	//  holding the server's private key.
+	privateKey?: string @protobuf(4,name=private_key)
+
+	//  REQUIRED if mode is `MUTUAL`. The path to a file containing
+	//  certificate authority certificates to use in verifying a presented
+	//  client side certificate.
+	caCertificates?: string @protobuf(5,name=ca_certificates)
+
+	//  The credentialName stands for a unique identifier that can be used
+	//  to identify the serverCertificate and the privateKey. The
+	//  credentialName appended with suffix "-cacert" is used to identify
+	//  the CaCertificates associated with this server. Gateway workloads
+	//  capable of fetching credentials from a remote credential store such
+	//  as Kubernetes secrets, will be configured to retrieve the
+	//  serverCertificate and the privateKey using credentialName, instead
+	//  of using the file system paths specified above. If using mutual TLS,
+	//  gateway workload instances will retrieve the CaCertificates using
+	//  credentialName-cacert. The semantics of the name are platform
+	//  dependent.  In Kubernetes, the default Istio supplied credential
+	//  server expects the credentialName to match the name of the
+	//  Kubernetes secret that holds the server certificate, the private
+	//  key, and the CA certificate (if using mutual TLS). Set the
+	//  `ISTIO_META_USER_SDS` metadata variable in the gateway's proxy to
+	//  enable the dynamic credential fetching feature.
+	credentialName?: string @protobuf(10,name=credential_name)
+
+	//  A list of alternate names to verify the subject identity in the
+	//  certificate presented by the client.
+	subjectAltNames?: [...string] @protobuf(6,name=subject_alt_names)
+
+	//  Optional: Minimum TLS protocol version.
+	minProtocolVersion?: Server_TLSOptions_TLSProtocol @protobuf(7,type=TLSProtocol,name=min_protocol_version)
+
+	//  Optional: Maximum TLS protocol version.
+	maxProtocolVersion?: Server_TLSOptions_TLSProtocol @protobuf(8,type=TLSProtocol,name=max_protocol_version)
+
+	//  Optional: If specified, only support the specified cipher list.
+	//  Otherwise default to the default cipher list supported by Envoy.
+	cipherSuites?: [...string] @protobuf(9,name=cipher_suites)
+}
+
+//  TLS modes enforced by the proxy
+Server_TLSOptions_TLSmode:
+	//  The SNI string presented by the client will be used as the match
+	//  criterion in a VirtualService TLS route to determine the
+	//  destination service from the service registry.
+	*"PASSTHROUGH" |
+
+	//  Secure connections with standard TLS semantics.
+	"SIMPLE" |
+
+	//  Secure connections to the upstream using mutual TLS by presenting
+	//  client certificates for authentication.
+	"MUTUAL" |
+
+	//  Similar to the passthrough mode, except servers with this TLS mode
+	//  do not require an associated VirtualService to map from the SNI
+	//  value to service in the registry. The destination details such as
+	//  the service/subset/port are encoded in the SNI value. The proxy
+	//  will forward to the upstream (Envoy) cluster (a group of
+	//  endpoints) specified by the SNI value. This server is typically
+	//  used to provide connectivity between services in disparate L3
+	//  networks that otherwise do not have direct connectivity between
+	//  their respective endpoints. Use of this mode assumes that both the
+	//  source and the destination are using Istio mTLS to secure traffic.
+	"AUTO_PASSTHROUGH"
+
+Server_TLSOptions_TLSmode_value: {
+	"PASSTHROUGH":      0
+	"SIMPLE":           1
+	"MUTUAL":           2
+	"AUTO_PASSTHROUGH": 3
+}
+
+//  TLS protocol versions.
+Server_TLSOptions_TLSProtocol:
+	*"TLS_AUTO" | //  Automatically choose the optimal TLS version.
+	"TLSV1_0" | //  TLS version 1.0
+	"TLSV1_1" | //  TLS version 1.1
+	"TLSV1_2" | //  TLS version 1.2
+	"TLSV1_3" //  TLS version 1.3
+
+Server_TLSOptions_TLSProtocol_value: {
+	"TLS_AUTO": 0
+	"TLSV1_0":  1
+	"TLSV1_1":  2
+	"TLSV1_2":  3
+	"TLSV1_3":  4
+}
+
+//  Port describes the properties of a specific port of a service.
+Port: {
+	//  REQUIRED: A valid non-negative integer port number.
+	number?: uint32 @protobuf(1)
+
+	//  REQUIRED: The protocol exposed on the port.
+	//  MUST BE one of HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS.
+	//  TLS implies the connection will be routed based on the SNI header to
+	//  the destination without terminating the TLS connection.
+	protocol?: string @protobuf(2)
+
+	//  Label assigned to the port.
+	name?: string @protobuf(3)
+}
diff --git a/internal/protobuf/testdata/mixer/v1/attributes.proto b/internal/protobuf/testdata/mixer/v1/attributes.proto
new file mode 100644
index 0000000..32fa4fc
--- /dev/null
+++ b/internal/protobuf/testdata/mixer/v1/attributes.proto
@@ -0,0 +1,148 @@
+// Copyright 2016 Istio Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package istio.mixer.v1;
+
+option go_package = "istio.io/api/mixer/v1";
+
+import "gogoproto/gogo.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/timestamp.proto";
+
+option (gogoproto.goproto_getters_all) = false;
+option (gogoproto.equal_all) = false;
+option (gogoproto.gostring_all) = false;
+option (gogoproto.stable_marshaler_all) = true;
+option cc_enable_arenas = true;
+
+// Attributes represents a set of typed name/value pairs. Many of Mixer's
+// API either consume and/or return attributes.
+//
+// Istio uses attributes to control the runtime behavior of services running in the service mesh.
+// Attributes are named and typed pieces of metadata describing ingress and egress traffic and the
+// environment this traffic occurs in. An Istio attribute carries a specific piece
+// of information such as the error code of an API request, the latency of an API request, or the
+// original IP address of a TCP connection. For example:
+//
+// ```yaml
+// request.path: xyz/abc
+// request.size: 234
+// request.time: 12:34:56.789 04/17/2017
+// source.ip: 192.168.0.1
+// target.service: example
+// ```
+//
+// A given Istio deployment has a fixed vocabulary of attributes that it understands.
+// The specific vocabulary is determined by the set of attribute producers being used
+// in the deployment. The primary attribute producer in Istio is Envoy, although
+// specialized Mixer adapters and services can also generate attributes.
+//
+// The common baseline set of attributes available in most Istio deployments is defined
+// [here](https://istio.io/docs/reference/config/policy-and-telemetry/attribute-vocabulary/).
+//
+// Attributes are strongly typed. The supported attribute types are defined by
+// [ValueType](https://github.com/istio/api/blob/master/policy/v1beta1/value_type.proto).
+// Each type of value is encoded into one of the so-called transport types present
+// in this message.
+//
+// Defines a map of attributes in uncompressed format.
+// Following places may use this message:
+// 1) Configure Istio/Proxy with static per-proxy attributes, such as source.uid.
+// 2) Service IDL definition to extract api attributes for active requests.
+// 3) Forward attributes from client proxy to server proxy for HTTP requests.
+message Attributes {
+  // A map of attribute name to its value.
+  map<string, AttributeValue> attributes = 1;
+
+  // Specifies one attribute value with different type.
+  message AttributeValue {
+    // The attribute value.
+    oneof value {
+      // Used for values of type STRING, DNS_NAME, EMAIL_ADDRESS, and URI
+      string string_value = 2;
+
+      // Used for values of type INT64
+      int64 int64_value = 3;
+
+      // Used for values of type DOUBLE
+      double double_value = 4;
+
+      // Used for values of type BOOL
+      bool bool_value = 5;
+
+      // Used for values of type BYTES
+      bytes bytes_value = 6;
+
+      // Used for values of type TIMESTAMP
+      google.protobuf.Timestamp timestamp_value = 7;
+
+      // Used for values of type DURATION
+      google.protobuf.Duration duration_value = 8;
+
+      // Used for values of type STRING_MAP
+      StringMap string_map_value = 9;
+    }
+  }
+
+  // Defines a string map.
+  message StringMap {
+    // Holds a set of name/value pairs.
+    map<string, string> entries = 1;
+  }
+}
+
+// Defines a list of attributes in compressed format optimized for transport.
+// Within this message, strings are referenced using integer indices into
+// one of two string dictionaries. Positive integers index into the global
+// deployment-wide dictionary, whereas negative integers index into the message-level
+// dictionary instead. The message-level dictionary is carried by the
+// `words` field of this message, the deployment-wide dictionary is determined via
+// configuration.
+message CompressedAttributes {
+  // The message-level dictionary.
+  repeated string words = 1;
+
+  // Holds attributes of type STRING, DNS_NAME, EMAIL_ADDRESS, URI
+  map<sint32, sint32> strings = 2;
+
+  // Holds attributes of type INT64
+  map<sint32, int64> int64s = 3;
+
+  // Holds attributes of type DOUBLE
+  map<sint32, double> doubles = 4;
+
+  // Holds attributes of type BOOL
+  map<sint32, bool> bools = 5;
+
+  // Holds attributes of type TIMESTAMP
+  map<sint32, google.protobuf.Timestamp> timestamps = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+
+  // Holds attributes of type DURATION
+  map<sint32, google.protobuf.Duration> durations = 7 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];
+
+  // Holds attributes of type BYTES
+  map<sint32, bytes> bytes = 8;
+
+  // Holds attributes of type STRING_MAP
+  map<sint32, StringMap> string_maps = 9 [(gogoproto.nullable) = false];
+}
+
+// A map of string to string. The keys and values in this map are dictionary
+// indices (see the [Attributes][istio.mixer.v1.CompressedAttributes] message for an explanation)
+message StringMap {
+  // Holds a set of name/value pairs.
+  map<sint32, sint32> entries = 1;
+}
diff --git a/internal/protobuf/testdata/mixer/v1/config/client/api_spec.proto b/internal/protobuf/testdata/mixer/v1/config/client/api_spec.proto
new file mode 100644
index 0000000..92dfefc
--- /dev/null
+++ b/internal/protobuf/testdata/mixer/v1/config/client/api_spec.proto
@@ -0,0 +1,241 @@
+// Copyright 2017 Istio Authors
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+syntax = "proto3";
+
+package istio.mixer.v1.config.client;
+
+option go_package="istio.io/api/mixer/v1/config/client";
+
+import "gogoproto/gogo.proto";
+
+import "mixer/v1/attributes.proto";
+import "mixer/v1/config/client/service.proto";
+
+option (gogoproto.goproto_getters_all) = false;
+option (gogoproto.equal_all) = false;
+option (gogoproto.gostring_all) = false;
+option (gogoproto.stable_marshaler_all) = true;
+
+// HTTPAPISpec defines the canonical configuration for generating
+// API-related attributes from HTTP requests based on the method and
+// uri templated path matches. It is sufficient for defining the API
+// surface of a service for the purposes of API attribute
+// generation. It is not intended to represent auth, quota,
+// documentation, or other information commonly found in other API
+// specifications, e.g. OpenAPI.
+//
+// Existing standards that define operations (or methods) in terms of
+// HTTP methods and paths can be normalized to this format for use in
+// Istio. For example, a simple petstore API described by OpenAPIv2
+// [here](https://github.com/googleapis/gnostic/blob/master/examples/v2.0/yaml/petstore-simple.yaml)
+// can be represented with the following HTTPAPISpec.
+//
+// ```yaml
+// apiVersion: config.istio.io/v1alpha2
+// kind: HTTPAPISpec
+// metadata:
+//   name: petstore
+//   namespace: default
+// spec:
+//   attributes:
+//     attributes:
+//       api.service:
+//         stringValue: petstore.swagger.io
+//       api.version:
+//         stringValue: 1.0.0
+//   patterns:
+//   - attributes:
+//       attributes:
+//         api.operation:
+//           stringValue: findPets
+//     httpMethod: GET
+//     uriTemplate: /api/pets
+//   - attributes:
+//       attributes:
+//         api.operation:
+//           stringValue: addPet
+//     httpMethod: POST
+//     uriTemplate: /api/pets
+//   - attributes:
+//       attributes:
+//         api.operation:
+//           stringValue: findPetById
+//     httpMethod: GET
+//     uriTemplate: /api/pets/{id}
+//   - attributes:
+//       attributes:
+//         api.operation:
+//           stringValue: deletePet
+//     httpMethod: DELETE
+//     uriTemplate: /api/pets/{id}
+//   api_keys:
+//   - query: api-key
+// ```
+message HTTPAPISpec {
+  // List of attributes that are generated when *any* of the HTTP
+  // patterns match. This list typically includes the "api.service"
+  // and "api.version" attributes.
+  Attributes attributes = 1;
+
+  // List of HTTP patterns to match.
+  repeated HTTPAPISpecPattern patterns = 2;
+
+  // List of APIKey that describes how to extract an API-KEY from an
+  // HTTP request. The first API-Key match found in the list is used,
+  // i.e. 'OR' semantics.
+  //
+  // The following default policies are used to generate the
+  // `request.api_key` attribute if no explicit APIKey is defined.
+  //
+  //     `query: key, `query: api_key`, and then `header: x-api-key`
+  //
+  repeated APIKey api_keys = 3;
+}
+
+// HTTPAPISpecPattern defines a single pattern to match against
+// incoming HTTP requests. The per-pattern list of attributes is
+// generated if both the http_method and uri_template match. In
+// addition, the top-level list of attributes in the HTTPAPISpec is also
+// generated.
+//
+// ```yaml
+// pattern:
+// - attributes
+//     api.operation: doFooBar
+//   httpMethod: GET
+//   uriTemplate: /foo/bar
+// ```
+message HTTPAPISpecPattern {
+  // List of attributes that are generated if the HTTP request matches
+  // the specified http_method and uri_template. This typically
+  // includes the "api.operation" attribute.
+  Attributes attributes = 1;
+
+  // HTTP request method to match against as defined by
+  // [rfc7231](https://tools.ietf.org/html/rfc7231#page-21). For
+  // example: GET, HEAD, POST, PUT, DELETE.
+  string http_method = 2;
+
+  oneof pattern {
+    // URI template to match against as defined by
+    // [rfc6570](https://tools.ietf.org/html/rfc6570). For example, the
+    // following are valid URI templates:
+    //
+    //     /pets
+    //     /pets/{id}
+    //     /dictionary/{term:1}/{term}
+    //     /search{?q*,lang}
+    //
+    string uri_template = 3;
+
+    // EXPERIMENTAL:
+    //
+    // ecmascript style regex-based match as defined by
+    // [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). For
+    // example,
+    //
+    //     "^/pets/(.*?)?"
+    //
+    string regex = 4;
+  }
+}
+
+// APIKey defines the explicit configuration for generating the
+// `request.api_key` attribute from HTTP requests.
+//
+// See [API Keys](https://swagger.io/docs/specification/authentication/api-keys)
+// for a general overview of API keys as defined by OpenAPI.
+message APIKey {
+  oneof key {
+    // API Key is sent as a query parameter. `query` represents the
+    // query string parameter name.
+    //
+    // For example, `query=api_key` should be used with the
+    // following request:
+    //
+    //     GET /something?api_key=abcdef12345
+    //
+    string query = 1;
+
+    // API key is sent in a request header. `header` represents the
+    // header name.
+    //
+    // For example, `header=X-API-KEY` should be used with the
+    // following request:
+    //
+    //     GET /something HTTP/1.1
+    //     X-API-Key: abcdef12345
+    //
+    string header = 2;
+
+    // API key is sent in a
+    // [cookie](https://swagger.io/docs/specification/authentication/cookie-authentication),
+    //
+    // For example, `cookie=X-API-KEY` should be used for the
+    // following request:
+    //
+    //     GET /something HTTP/1.1
+    //     Cookie: X-API-KEY=abcdef12345
+    //
+    string cookie = 3;
+  }
+}
+
+// HTTPAPISpecReference defines a reference to an HTTPAPISpec. This is
+// typically used for establishing bindings between an HTTPAPISpec and an
+// IstioService. For example, the following defines an
+// HTTPAPISpecReference for service `foo` in namespace `bar`.
+//
+// ```yaml
+// - name: foo
+//   namespace: bar
+// ```
+message HTTPAPISpecReference {
+  // REQUIRED. The short name of the HTTPAPISpec. This is the resource
+  // name defined by the metadata name field.
+  string name = 1;
+
+  // Optional namespace of the HTTPAPISpec. Defaults to the encompassing
+  // HTTPAPISpecBinding's metadata namespace field.
+  string namespace = 2;
+}
+
+// HTTPAPISpecBinding defines the binding between HTTPAPISpecs and one or more
+// IstioService. For example, the following establishes a binding
+// between the HTTPAPISpec `petstore` and service `foo` in namespace `bar`.
+//
+// ```yaml
+// apiVersion: config.istio.io/v1alpha2
+// kind: HTTPAPISpecBinding
+// metadata:
+//   name: my-binding
+//   namespace: default
+// spec:
+//   services:
+//   - name: foo
+//     namespace: bar
+//   api_specs:
+//   - name: petstore
+//     namespace: default
+// ```
+message HTTPAPISpecBinding {
+  // REQUIRED. One or more services to map the listed HTTPAPISpec onto.
+  repeated IstioService services = 1;
+
+  // REQUIRED. One or more HTTPAPISpec references that should be mapped to
+  // the specified service(s). The aggregate collection of match
+  // conditions defined in the HTTPAPISpecs should not overlap.
+  repeated HTTPAPISpecReference api_specs = 2;
+}
diff --git a/internal/protobuf/testdata/mixer/v1/config/client/client_config.proto b/internal/protobuf/testdata/mixer/v1/config/client/client_config.proto
new file mode 100644
index 0000000..a229699
--- /dev/null
+++ b/internal/protobuf/testdata/mixer/v1/config/client/client_config.proto
@@ -0,0 +1,198 @@
+// Copyright 2017 Istio Authors
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+syntax = "proto3";
+
+import "gogoproto/gogo.proto";
+import "google/protobuf/duration.proto";
+
+import "mixer/v1/attributes.proto";
+import "mixer/v1/config/client/api_spec.proto";
+import "mixer/v1/config/client/quota.proto";
+
+// $title: Mixer Client
+// $description: Configuration state for the Mixer client library.
+// $location: https://istio.io/docs/reference/config/policy-and-telemetry/istio.mixer.v1.config.client
+
+// Describes the configuration state for the Mixer client library that's built into Envoy.
+package istio.mixer.v1.config.client;
+
+option go_package = "istio.io/api/mixer/v1/config/client";
+
+option (gogoproto.goproto_getters_all) = false;
+option (gogoproto.equal_all) = false;
+option (gogoproto.gostring_all) = false;
+option (gogoproto.stable_marshaler_all) = true;
+
+// Specifies the behavior when the client is unable to connect to Mixer.
+message NetworkFailPolicy {
+  // Describes the policy.
+  enum FailPolicy {
+    // If network connection fails, request is allowed and delivered to the
+    // service.
+    FAIL_OPEN = 0;
+
+    // If network connection fails, request is rejected.
+    FAIL_CLOSE = 1;
+  }
+
+  // Specifies the behavior when the client is unable to connect to Mixer.
+  FailPolicy policy = 1;
+
+  // Max retries on transport error.
+  uint32 max_retry = 2;
+
+  // Base time to wait between retries.  Will be adjusted by exponential
+  // backoff and jitter.
+  google.protobuf.Duration base_retry_wait = 3;
+
+  // Max time to wait between retries.
+  google.protobuf.Duration max_retry_wait = 4;
+}
+
+// Defines the per-service client configuration.
+message ServiceConfig {
+  // If true, do not call Mixer Check.
+  bool disable_check_calls = 1;
+
+  // If true, do not call Mixer Report.
+  bool disable_report_calls = 2;
+
+  // Send these attributes to Mixer in both Check and Report. This
+  // typically includes the "destination.service" attribute.
+  // In case of a per-route override, per-route attributes take precedence
+  // over the attributes supplied in the client configuration.
+  Attributes mixer_attributes = 3;
+
+  // HTTP API specifications to generate API attributes.
+  repeated HTTPAPISpec http_api_spec = 4;
+
+  // Quota specifications to generate quota requirements.
+  repeated QuotaSpec quota_spec = 5;
+
+  // Specifies the behavior when the client is unable to connect to Mixer.
+  // This is the service-level policy. It overrides
+  // [mesh-level
+  // policy][istio.mixer.v1.config.client.TransportConfig.network_fail_policy].
+  NetworkFailPolicy network_fail_policy = 7;
+
+  // Default attributes to forward to upstream. This typically
+  // includes the "source.ip" and "source.uid" attributes.
+  // In case of a per-route override, per-route attributes take precedence
+  // over the attributes supplied in the client configuration.
+  //
+  // Forwarded attributes take precedence over the static Mixer attributes.
+  // The full order of application is as follows:
+  // 1. static Mixer attributes from the filter config;
+  // 2. static Mixer attributes from the route config;
+  // 3. forwarded attributes from the source filter config (if any);
+  // 4. forwarded attributes from the source route config (if any);
+  // 5. derived attributes from the request metadata.
+  Attributes forward_attributes = 8;
+}
+
+// Defines the transport config on how to call Mixer.
+message TransportConfig {
+  // The flag to disable check cache.
+  bool disable_check_cache = 1;
+
+  // The flag to disable quota cache.
+  bool disable_quota_cache = 2;
+
+  // The flag to disable report batch.
+  bool disable_report_batch = 3;
+
+  // Specifies the behavior when the client is unable to connect to Mixer.
+  // This is the mesh level policy. The default value for policy is FAIL_OPEN.
+  NetworkFailPolicy network_fail_policy = 4;
+
+  // Specify refresh interval to write Mixer client statistics to Envoy share
+  // memory. If not specified, the interval is 10 seconds.
+  google.protobuf.Duration stats_update_interval = 5;
+
+  // Name of the cluster that will forward check calls to a pool of mixer
+  // servers. Defaults to "mixer_server". By using different names for
+  // checkCluster and reportCluster, it is possible to have one set of
+  // Mixer servers handle check calls, while another set of Mixer servers
+  // handle report calls.
+  //
+  // NOTE: Any value other than the default "mixer_server" will require the
+  // Istio Grafana dashboards to be reconfigured to use the new name.
+  string check_cluster = 6;
+
+  // Name of the cluster that will forward report calls to a pool of mixer
+  // servers. Defaults to "mixer_server". By using different names for
+  // checkCluster and reportCluster, it is possible to have one set of
+  // Mixer servers handle check calls, while another set of Mixer servers
+  // handle report calls.
+  //
+  // NOTE: Any value other than the default "mixer_server" will require the
+  // Istio Grafana dashboards to be reconfigured to use the new name.
+  string report_cluster = 7;
+
+  // Default attributes to forward to Mixer upstream. This typically
+  // includes the "source.ip" and "source.uid" attributes. These
+  // attributes are consumed by the proxy in front of mixer.
+  Attributes attributes_for_mixer_proxy = 8;
+}
+
+// Defines the client config for HTTP.
+message HttpClientConfig {
+  // The transport config.
+  TransportConfig transport = 1;
+
+  // Map of control configuration indexed by destination.service. This
+  // is used to support per-service configuration for cases where a
+  // mixerclient serves multiple services.
+  map<string, ServiceConfig> service_configs = 2;
+
+  // Default destination service name if none was specified in the
+  // client request.
+  string default_destination_service = 3;
+
+  // Default attributes to send to Mixer in both Check and
+  // Report. This typically includes "destination.ip" and
+  // "destination.uid" attributes.
+  Attributes mixer_attributes = 4;
+
+  // Default attributes to forward to upstream. This typically
+  // includes the "source.ip" and "source.uid" attributes.
+  Attributes forward_attributes = 5;
+}
+
+// Defines the client config for TCP.
+message TcpClientConfig {
+  // The transport config.
+  TransportConfig transport = 1;
+
+  // Default attributes to send to Mixer in both Check and
+  // Report. This typically includes "destination.ip" and
+  // "destination.uid" attributes.
+  Attributes mixer_attributes = 2;
+
+  // If set to true, disables Mixer check calls.
+  bool disable_check_calls = 3;
+
+  // If set to true, disables Mixer check calls.
+  bool disable_report_calls = 4;
+
+  // Quota specifications to generate quota requirements.
+  // It applies on the new TCP connections.
+  QuotaSpec connection_quota_spec = 5;
+
+  // Specify report interval to send periodical reports for long TCP
+  // connections. If not specified, the interval is 10 seconds. This interval
+  // should not be less than 1 second, otherwise it will be reset to 1 second.
+  google.protobuf.Duration report_interval = 6;
+}
diff --git a/internal/protobuf/testdata/mixer/v1/config/client/quota.proto b/internal/protobuf/testdata/mixer/v1/config/client/quota.proto
new file mode 100644
index 0000000..5ea594c
--- /dev/null
+++ b/internal/protobuf/testdata/mixer/v1/config/client/quota.proto
@@ -0,0 +1,145 @@
+// Copyright 2017 Istio Authors
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+syntax = "proto3";
+
+package istio.mixer.v1.config.client;
+
+option go_package="istio.io/api/mixer/v1/config/client";
+
+import "gogoproto/gogo.proto";
+import "mixer/v1/config/client/service.proto";
+
+option (gogoproto.goproto_getters_all) = false;
+option (gogoproto.equal_all) = false;
+option (gogoproto.gostring_all) = false;
+option (gogoproto.stable_marshaler_all) = true;
+
+// Specifies runtime quota rules.
+//  * Uses Istio attributes to match individual requests
+//  * Specifies list of quotas to use for matched requests.
+//
+// Example1:
+// Charge "request_count" quota with 1 amount for all requests.
+//
+//   QuotaSpec:
+//     - rules
+//       - quotas:
+//           quota: request_count
+//           charge: 1
+//
+// Example2:
+// For HTTP POST requests with path are prefixed with /books or
+// api.operation is create_books, charge two quotas:
+// * write_count of 1 amount
+// * request_count of 5 amount.
+//
+// ```yaml
+// QuotaSpec:
+//   - rules:
+//     - match:
+//         clause:
+//           request.path:
+//             string_prefix: /books
+//           request.http_method:
+//             string_exact: POST
+//     - match:
+//         clause:
+//           api.operation:
+//             string_exact: create_books
+//     - quotas:
+//         quota: write_count
+//         charge: 1
+//     - quotas:
+//         quota: request_count
+//         charge: 5
+// ```
+
+// Determines the quotas used for individual requests.
+message QuotaSpec {
+  // A list of Quota rules.
+  repeated QuotaRule rules = 1;
+}
+
+// Specifies a rule with list of matches and list of quotas.
+// If any clause matched, the list of quotas will be used.
+message QuotaRule {
+  // If empty, match all request.
+  // If any of match is true, it is matched.
+  repeated AttributeMatch match = 1;
+
+  // The list of quotas to charge.
+  repeated Quota quotas = 2;
+}
+
+// Describes how to match a given string in HTTP headers. Match is
+// case-sensitive.
+message StringMatch {
+  oneof match_type {
+    // exact string match
+    string exact = 1;
+    // prefix-based match
+    string prefix = 2;
+    // ECMAscript style regex-based match
+    string regex = 3;
+  }
+}
+
+// Specifies a match clause to match Istio attributes
+message AttributeMatch {
+  // Map of attribute names to StringMatch type.
+  // Each map element specifies one condition to match.
+  //
+  // Example:
+  //
+  //   clause:
+  //     source.uid:
+  //       exact: SOURCE_UID
+  //     request.http_method:
+  //       exact: POST
+  map<string, StringMatch> clause = 1;
+}
+
+// Specifies a quota to use with quota name and amount.
+message Quota {
+  // The quota name to charge
+  string quota = 1;
+
+  // The quota amount to charge
+  int64  charge = 2;
+}
+
+// QuotaSpecBinding defines the binding between QuotaSpecs and one or more
+// IstioService.
+message QuotaSpecBinding {
+  // REQUIRED. One or more services to map the listed QuotaSpec onto.
+  repeated IstioService services = 1;
+
+  // QuotaSpecReference uniquely identifies the QuotaSpec used in the
+  // Binding.
+  message QuotaSpecReference {
+    // REQUIRED. The short name of the QuotaSpec. This is the resource
+    // name defined by the metadata name field.
+    string name = 1;
+
+    // Optional namespace of the QuotaSpec. Defaults to the value of the
+    // metadata namespace field.
+    string namespace = 2;
+  }
+
+  // REQUIRED. One or more QuotaSpec references that should be mapped to
+  // the specified service(s). The aggregate collection of match
+  // conditions defined in the QuotaSpecs should not overlap.
+  repeated QuotaSpecReference quota_specs = 2;
+}
diff --git a/internal/protobuf/testdata/mixer/v1/config/client/service.proto b/internal/protobuf/testdata/mixer/v1/config/client/service.proto
new file mode 100644
index 0000000..01de2e9
--- /dev/null
+++ b/internal/protobuf/testdata/mixer/v1/config/client/service.proto
@@ -0,0 +1,58 @@
+// Copyright 2017 Istio Authors
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+syntax = "proto3";
+
+package istio.mixer.v1.config.client;
+
+option go_package="istio.io/api/mixer/v1/config/client";
+
+import "gogoproto/gogo.proto";
+
+option (gogoproto.goproto_getters_all) = false;
+option (gogoproto.equal_all) = false;
+option (gogoproto.gostring_all) = false;
+option (gogoproto.stable_marshaler_all) = true;
+
+// NOTE: this is a duplicate of proxy.v1.config.IstioService from
+// proxy/v1alpha1/config/route_rules.proto.
+//
+// Mixer protobufs have gogoproto specific options which are not
+// compatiable with the proxy's vanilla protobufs. Ideally, these
+// protobuf options be reconciled so fundamental Istio concepts and
+// types can be shared by components. Until then, make a copy of
+// IstioService for mixerclient to use.
+
+// IstioService identifies a service and optionally service version.
+// The FQDN of the service is composed from the name, namespace, and implementation-specific domain suffix
+// (e.g. on Kubernetes, "reviews" + "default" + "svc.cluster.local" -> "reviews.default.svc.cluster.local").
+message IstioService {
+  // The short name of the service such as "foo".
+  string name = 1;
+
+  // Optional namespace of the service. Defaults to value of metadata namespace field.
+  string namespace = 2;
+
+  // Domain suffix used to construct the service FQDN in implementations that support such specification.
+  string domain = 3;
+
+  // The service FQDN.
+  string service = 4;
+
+  // Optional one or more labels that uniquely identify the service version.
+  //
+  // *Note:* When used for a VirtualService destination, labels MUST be empty.
+  //
+  map<string, string> labels = 5;
+}
diff --git a/internal/protobuf/testdata/mixer/v1/mixer.proto b/internal/protobuf/testdata/mixer/v1/mixer.proto
new file mode 100644
index 0000000..04ace67
--- /dev/null
+++ b/internal/protobuf/testdata/mixer/v1/mixer.proto
@@ -0,0 +1,265 @@
+// Copyright 2016 Istio Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+// This package defines the Mixer API that the sidecar proxy uses to perform
+// precondition checks, manage quotas, and report telemetry.
+package istio.mixer.v1;
+
+option go_package = "istio.io/api/mixer/v1";
+option cc_generic_services = true;
+
+import "gogoproto/gogo.proto";
+import "google/protobuf/duration.proto";
+import "google/rpc/status.proto";
+import "mixer/v1/attributes.proto";
+
+option (gogoproto.goproto_getters_all) = false;
+option (gogoproto.equal_all) = false;
+option (gogoproto.gostring_all) = false;
+option cc_enable_arenas = true;
+
+// Mixer provides three core features:
+//
+// - *Precondition Checking*. Enables callers to verify a number of preconditions
+// before responding to an incoming request from a service consumer.
+// Preconditions can include whether the service consumer is properly
+// authenticated, is on the service’s whitelist, passes ACL checks, and more.
+//
+// - *Quota Management*. Enables services to allocate and free quota on a number
+// of dimensions, Quotas are used as a relatively simple resource management tool
+// to provide some fairness between service consumers when contending for limited
+// resources. Rate limits are examples of quotas.
+//
+// - *Telemetry Reporting*. Enables services to report logging and monitoring.
+// In the future, it will also enable tracing and billing streams intended for
+// both the service operator as well as for service consumers.
+service Mixer {
+  // Checks preconditions and allocate quota before performing an operation.
+  // The preconditions enforced depend on the set of supplied attributes and
+  // the active configuration.
+  rpc Check(CheckRequest) returns (CheckResponse) {}
+
+  // Reports telemetry, such as logs and metrics.
+  // The reported information depends on the set of supplied attributes and the
+  // active configuration.
+  rpc Report(ReportRequest) returns (ReportResponse) {}
+}
+
+// Used to get a thumbs-up/thumbs-down before performing an action.
+message CheckRequest {
+  // parameters for a quota allocation
+  message QuotaParams {
+    // Amount of quota to allocate
+    int64 amount = 1;
+
+    // When true, supports returning less quota than what was requested.
+    bool best_effort = 2;
+  }
+
+  // The attributes to use for this request.
+  //
+  // Mixer's configuration determines how these attributes are used to
+  // establish the result returned in the response.
+  CompressedAttributes attributes = 1 [(gogoproto.nullable) = false];
+
+  // The number of words in the global dictionary, used with to populate the attributes.
+  // This value is used as a quick way to determine whether the client is using a dictionary that
+  // the server understands.
+  uint32 global_word_count = 2;
+
+  // Used for deduplicating `Check` calls in the case of failed RPCs and retries. This should be a UUID
+  // per call, where the same UUID is used for retries of the same call.
+  string deduplication_id = 3;
+
+  // The individual quotas to allocate
+  map<string, QuotaParams> quotas = 4 [(gogoproto.nullable) = false];
+}
+
+// The response generated by the Check method.
+message CheckResponse {
+
+  // Expresses the result of a precondition check.
+  message PreconditionResult {
+    reserved 4;
+
+    // A status code of OK indicates all preconditions were satisfied. Any other code indicates not
+    // all preconditions were satisfied and details describe why.
+    google.rpc.Status status = 1 [(gogoproto.nullable) = false];
+
+    // The amount of time for which this result can be considered valid.
+    google.protobuf.Duration valid_duration = 2 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];
+
+    // The number of uses for which this result can be considered valid.
+    int32 valid_use_count = 3;
+
+    // The total set of attributes that were used in producing the result
+    // along with matching conditions.
+    ReferencedAttributes referenced_attributes = 5;
+
+    // An optional routing directive, used to manipulate the traffic metadata
+    // whenever all preconditions are satisfied.
+    RouteDirective route_directive = 6;
+  }
+
+  // Expresses the result of a quota allocation.
+  message QuotaResult {
+    // The amount of time for which this result can be considered valid.
+    google.protobuf.Duration valid_duration = 1 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];
+
+    // The amount of granted quota. When `QuotaParams.best_effort` is true, this will be >= 0.
+    // If `QuotaParams.best_effort` is false, this will be either 0 or >= `QuotaParams.amount`.
+    int64 granted_amount = 2;
+
+    // The total set of attributes that were used in producing the result
+    // along with matching conditions.
+    ReferencedAttributes referenced_attributes = 5 [(gogoproto.nullable) = false];
+  }
+
+  // The precondition check results.
+  PreconditionResult precondition = 2 [(gogoproto.nullable) = false];
+
+  // The resulting quota, one entry per requested quota.
+  map<string, QuotaResult> quotas = 3 [(gogoproto.nullable) = false];
+}
+
+// Describes the attributes that were used to determine the response.
+// This can be used to construct a response cache.
+message ReferencedAttributes {
+  // How an attribute's value was matched
+  enum Condition {
+    CONDITION_UNSPECIFIED = 0;    // should not occur
+    ABSENCE = 1;                  // match when attribute doesn't exist
+    EXACT = 2;                    // match when attribute value is an exact byte-for-byte match
+    REGEX = 3;                    // match when attribute value matches the included regex
+  }
+
+  // Describes a single attribute match.
+  message AttributeMatch {
+    // The name of the attribute. This is a dictionary index encoded in a manner identical
+    // to all strings in the [CompressedAttributes][istio.mixer.v1.CompressedAttributes] message.
+    sint32 name = 1;
+
+    // The kind of match against the attribute value.
+    Condition condition = 2;
+
+    // If a REGEX condition is provided for a STRING_MAP attribute,
+    // clients should use the regex value to match against map keys.
+    string regex = 3;
+
+    // A key in a STRING_MAP. When multiple keys from a STRING_MAP
+    // attribute were referenced, there will be multiple AttributeMatch
+    // messages with different map_key values. Values for map_key SHOULD
+    // be ignored for attributes that are not STRING_MAP.
+    //
+    // Indices for the keys are used (taken either from the
+    // message dictionary from the `words` field or the global dictionary).
+    //
+    // If no map_key value is provided for a STRING_MAP attribute, the
+    // entire STRING_MAP will be used.
+    sint32 map_key = 4;
+  }
+
+  // The message-level dictionary. Refer to [CompressedAttributes][istio.mixer.v1.CompressedAttributes] for information
+  // on using dictionaries.
+  repeated string words = 1;
+
+  // Describes a set of attributes.
+  repeated AttributeMatch attribute_matches = 2 [(gogoproto.nullable) = false];
+}
+
+// Operation on HTTP headers to replace, append, or remove a header. Header
+// names are normalized to lower-case with dashes, e.g.  "x-request-id".
+// Pseudo-headers ":path", ":authority", and ":method" are supported to modify
+// the request headers.
+message HeaderOperation {
+  // Operation type.
+  enum Operation {
+    REPLACE = 0;  // replaces the header with the given name
+    REMOVE = 1;   // removes the header with the given name (the value is ignored)
+    APPEND = 2;   // appends the value to the header value, or sets it if not present
+  }
+  // Header name.
+  string name = 1;
+
+  // Header value.
+  string value = 2;
+
+  // Header operation.
+  Operation operation = 3;
+}
+
+// Expresses the routing manipulation actions to be performed on behalf of
+// Mixer in response to a precondition check.
+message RouteDirective {
+  // Operations on the request headers.
+  repeated HeaderOperation request_header_operations = 1 [(gogoproto.nullable) = false];
+
+  // Operations on the response headers.
+  repeated HeaderOperation response_header_operations = 2 [(gogoproto.nullable) = false];
+
+  // If set, enables a direct response without proxying the request to the routing
+  // destination. Required to be a value in the 2xx or 3xx range.
+  uint32 direct_response_code = 3;
+
+  // Supplies the response body for the direct response.
+  // If this setting is omitted, no body is included in the generated response.
+  string direct_response_body = 4;
+}
+
+// Used to report telemetry after performing one or more actions.
+message ReportRequest {
+  // next value: 5
+
+  // Used to signal how the sets of compressed attributes should be reconstitued server-side.
+  enum RepeatedAttributesSemantics {
+    // Use delta encoding between sets of compressed attributes to reduce the overall on-wire
+    // request size. Each individual set of attributes is used to modify the previous set.
+    // NOTE: There is no way with this encoding to specify attribute value deletion. This 
+    // option should be used with extreme caution.
+    DELTA_ENCODING = 0;
+
+    // Treat each set of compressed attributes as complete - independent from other sets
+    // in this request. This will result in on-wire duplication of attributes and values, but
+    // will allow for proper accounting of absent values in overall encoding.
+    INDEPENDENT_ENCODING = 1;
+  }
+
+  // The attributes to use for this request.
+  //
+  // Each `Attributes` element represents the state of a single action. Multiple actions
+  // can be provided in a single message in order to improve communication efficiency. The
+  // client can accumulate a set of actions and send them all in one single message.
+  repeated CompressedAttributes attributes = 1 [(gogoproto.nullable) = false];
+
+  // Indicates how to decode the attributes sets in this request.
+  RepeatedAttributesSemantics repeated_attributes_semantics = 4;
+
+  // The default message-level dictionary for all the attributes.
+  // Individual attribute messages can have their own dictionaries, but if they don't
+  // then this set of words, if it is provided, is used instead.
+  //
+  // This makes it possible to share the same dictionary for all attributes in this
+  // request, which can substantially reduce the overall request size.
+  repeated string default_words = 2;
+
+  // The number of words in the global dictionary.
+  // To detect global dictionary out of sync between client and server.
+  uint32 global_word_count = 3;
+}
+
+// Used to carry responses to telemetry reports
+message ReportResponse {
+}
diff --git a/internal/protobuf/testdata/networking/v1alpha3/gateway.proto b/internal/protobuf/testdata/networking/v1alpha3/gateway.proto
new file mode 100644
index 0000000..e06fe5d
--- /dev/null
+++ b/internal/protobuf/testdata/networking/v1alpha3/gateway.proto
@@ -0,0 +1,448 @@
+// Copyright 2019 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Copyright 2017 Istio Authors
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+
+syntax = "proto3";
+
+// $title: Gateway
+// $description: Configuration affecting edge load balancer.
+// $location: https://istio.io/docs/reference/config/networking/v1alpha3/gateway.html
+
+// `Gateway` describes a load balancer operating at the edge of the mesh
+// receiving incoming or outgoing HTTP/TCP connections. The specification
+// describes a set of ports that should be exposed, the type of protocol to
+// use, SNI configuration for the load balancer, etc.
+//
+// For example, the following Gateway configuration sets up a proxy to act
+// as a load balancer exposing port 80 and 9080 (http), 443 (https),
+// 9443(https) and port 2379 (TCP) for ingress.  The gateway will be
+// applied to the proxy running on a pod with labels `app:
+// my-gateway-controller`. While Istio will configure the proxy to listen
+// on these ports, it is the responsibility of the user to ensure that
+// external traffic to these ports are allowed into the mesh.
+//
+// ```yaml
+// apiVersion: networking.istio.io/v1alpha3
+// kind: Gateway
+// metadata:
+//   name: my-gateway
+//   namespace: some-config-namespace
+// spec:
+//   selector:
+//     app: my-gateway-controller
+//   servers:
+//   - port:
+//       number: 80
+//       name: http
+//       protocol: HTTP
+//     hosts:
+//     - uk.bookinfo.com
+//     - eu.bookinfo.com
+//     tls:
+//       httpsRedirect: true # sends 301 redirect for http requests
+//   - port:
+//       number: 443
+//       name: https-443
+//       protocol: HTTPS
+//     hosts:
+//     - uk.bookinfo.com
+//     - eu.bookinfo.com
+//     tls:
+//       mode: SIMPLE # enables HTTPS on this port
+//       serverCertificate: /etc/certs/servercert.pem
+//       privateKey: /etc/certs/privatekey.pem
+//   - port:
+//       number: 9443
+//       name: https-9443
+//       protocol: HTTPS
+//     hosts:
+//     - "bookinfo-namespace/*.bookinfo.com"
+//     tls:
+//       mode: SIMPLE # enables HTTPS on this port
+//       credentialName: bookinfo-secret # fetches certs from Kubernetes secret
+//   - port:
+//       number: 9080
+//       name: http-wildcard
+//       protocol: HTTP
+//     hosts:
+//     - "*"
+//   - port:
+//       number: 2379 # to expose internal service via external port 2379
+//       name: mongo
+//       protocol: MONGO
+//     hosts:
+//     - "*"
+// ```
+//
+// The Gateway specification above describes the L4-L6 properties of a load
+// balancer. A `VirtualService` can then be bound to a gateway to control
+// the forwarding of traffic arriving at a particular host or gateway port.
+//
+// For example, the following VirtualService splits traffic for
+// `https://uk.bookinfo.com/reviews`, `https://eu.bookinfo.com/reviews`,
+// `http://uk.bookinfo.com:9080/reviews`,
+// `http://eu.bookinfo.com:9080/reviews` into two versions (prod and qa) of
+// an internal reviews service on port 9080. In addition, requests
+// containing the cookie "user: dev-123" will be sent to special port 7777
+// in the qa version. The same rule is also applicable inside the mesh for
+// requests to the "reviews.prod.svc.cluster.local" service. This rule is
+// applicable across ports 443, 9080. Note that `http://uk.bookinfo.com`
+// gets redirected to `https://uk.bookinfo.com` (i.e. 80 redirects to 443).
+//
+// ```yaml
+// apiVersion: networking.istio.io/v1alpha3
+// kind: VirtualService
+// metadata:
+//   name: bookinfo-rule
+//   namespace: bookinfo-namespace
+// spec:
+//   hosts:
+//   - reviews.prod.svc.cluster.local
+//   - uk.bookinfo.com
+//   - eu.bookinfo.com
+//   gateways:
+//   - some-config-namespace/my-gateway
+//   - mesh # applies to all the sidecars in the mesh
+//   http:
+//   - match:
+//     - headers:
+//         cookie:
+//           exact: "user=dev-123"
+//     route:
+//     - destination:
+//         port:
+//           number: 7777
+//         host: reviews.qa.svc.cluster.local
+//   - match:
+//     - uri:
+//         prefix: /reviews/
+//     route:
+//     - destination:
+//         port:
+//           number: 9080 # can be omitted if it's the only port for reviews
+//         host: reviews.prod.svc.cluster.local
+//       weight: 80
+//     - destination:
+//         host: reviews.qa.svc.cluster.local
+//       weight: 20
+// ```
+//
+// The following VirtualService forwards traffic arriving at (external)
+// port 27017 to internal Mongo server on port 5555. This rule is not
+// applicable internally in the mesh as the gateway list omits the
+// reserved name `mesh`.
+//
+// ```yaml
+// apiVersion: networking.istio.io/v1alpha3
+// kind: VirtualService
+// metadata:
+//   name: bookinfo-Mongo
+//   namespace: bookinfo-namespace
+// spec:
+//   hosts:
+//   - mongosvr.prod.svc.cluster.local # name of internal Mongo service
+//   gateways:
+//   - some-config-namespace/my-gateway # can omit the namespace if gateway is in same
+//                                        namespace as virtual service.
+//   tcp:
+//   - match:
+//     - port: 27017
+//     route:
+//     - destination:
+//         host: mongo.prod.svc.cluster.local
+//         port:
+//           number: 5555
+// ```
+//
+// It is possible to restrict the set of virtual services that can bind to
+// a gateway server using the namespace/hostname syntax in the hosts field.
+// For example, the following Gateway allows any virtual service in the ns1
+// namespace to bind to it, while restricting only the virtual service with
+// foo.bar.com host in the ns2 namespace to bind to it.
+//
+// ```yaml
+// apiVersion: networking.istio.io/v1alpha3
+// kind: Gateway
+// metadata:
+//   name: my-gateway
+//   namespace: some-config-namespace
+// spec:
+//   selector:
+//     app: my-gateway-controller
+//   servers:
+//   - port:
+//       number: 80
+//       name: http
+//       protocol: HTTP
+//     hosts:
+//     - "ns1/*"
+//     - "ns2/foo.bar.com"
+// ```
+//
+package istio.networking.v1alpha3;
+
+import "cuelang/cue.proto";
+
+// GO PACKAGE
+option go_package = "istio.io/api/networking/v1alpha3"; // INLINE
+
+message Gateway {
+  // REQUIRED: A list of server specifications.
+  repeated Server servers = 1;
+
+  // REQUIRED: One or more labels that indicate a specific set of pods/VMs
+  // on which this gateway configuration should be applied. The scope of
+  // label search is restricted to the configuration namespace in which the
+  // the resource is present. In other words, the Gateway resource must
+  // reside in the same namespace as the gateway workload instance.
+  map<string, string> selector = 2 [ (cue.val) = "{<name>: name}"];
+}
+
+// `Server` describes the properties of the proxy on a given load balancer
+// port. For example,
+//
+// ```yaml
+// apiVersion: networking.istio.io/v1alpha3
+// kind: Gateway
+// metadata:
+//   name: my-ingress
+// spec:
+//   selector:
+//     app: my-ingress-gateway
+//   servers:
+//   - port:
+//       number: 80
+//       name: http2
+//       protocol: HTTP2
+//     hosts:
+//     - "*"
+// ```
+//
+// Another example
+//
+// ```yaml
+// apiVersion: networking.istio.io/v1alpha3
+// kind: Gateway
+// metadata:
+//   name: my-tcp-ingress
+// spec:
+//   selector:
+//     app: my-tcp-ingress-gateway
+//   servers:
+//   - port:
+//       number: 27018
+//       name: mongo
+//       protocol: MONGO
+//     hosts:
+//     - "*"
+// ```
+//
+// The following is an example of TLS configuration for port 443
+//
+// ```yaml
+// apiVersion: networking.istio.io/v1alpha3
+// kind: Gateway
+// metadata:
+//   name: my-tls-ingress
+// spec:
+//   selector:
+//     app: my-tls-ingress-gateway
+//   servers:
+//   - port:
+//       number: 443
+//       name: https
+//       protocol: HTTPS
+//     hosts:
+//     - "*"
+//     tls:
+//       mode: SIMPLE
+//       serverCertificate: /etc/certs/server.pem
+//       privateKey: /etc/certs/privatekey.pem
+// ```
+message Server {
+  // REQUIRED: The Port on which the proxy should listen for incoming
+  // connections.
+  Port port = 1 [(cue.val) = ">10 & <100"];
+
+  // $hide_from_docs
+  // The ip or the Unix domain socket to which the listener should be bound
+  // to. Format: `x.x.x.x` or `unix:///path/to/uds` or `unix://@foobar`
+  // (Linux abstract namespace). When using Unix domain sockets, the port
+  // number should be 0.
+  string bind = 4;
+
+  // REQUIRED. One or more hosts exposed by this gateway.
+  // While typically applicable to
+  // HTTP services, it can also be used for TCP services using TLS with SNI.
+  // A host is specified as a `dnsName` with an optional `namespace/` prefix.
+  // The `dnsName` should be specified using FQDN format, optionally including
+  // a wildcard character in the left-most component (e.g., `prod/*.example.com`).
+  // Set the `dnsName` to `*` to select all `VirtualService` hosts from the
+  // specified namespace (e.g.,`prod/*`). If no `namespace/` is specified,
+  // the `VirtualService` hosts will be selected from any available namespace.
+  // Any associated `DestinationRule` in the same namespace will also be used.
+  //
+  // A `VirtualService` must be bound to the gateway and must have one or
+  // more hosts that match the hosts specified in a server. The match
+  // could be an exact match or a suffix match with the server's hosts. For
+  // example, if the server's hosts specifies `*.example.com`, a
+  // `VirtualService` with hosts `dev.example.com` or `prod.example.com` will
+  // match. However, a `VirtualService` with host `example.com` or
+  // `newexample.com` will not match.
+  //
+  // NOTE: Only virtual services exported to the gateway's namespace
+  // (e.g., `exportTo` value of `*`) can be referenced.
+  // Private configurations (e.g., `exportTo` set to `.`) will not be
+  // available. Refer to the `exportTo` setting in `VirtualService`,
+  // `DestinationRule`, and `ServiceEntry` configurations for details.
+  repeated string hosts = 2;
+
+  message TLSOptions {
+    // If set to true, the load balancer will send a 301 redirect for all
+    // http connections, asking the clients to use HTTPS.
+    bool https_redirect = 1;
+
+    // TLS modes enforced by the proxy
+    enum TLSmode {
+      // The SNI string presented by the client will be used as the match
+      // criterion in a VirtualService TLS route to determine the
+      // destination service from the service registry.
+      PASSTHROUGH = 0;
+
+      // Secure connections with standard TLS semantics.
+      SIMPLE = 1;
+
+      // Secure connections to the upstream using mutual TLS by presenting
+      // client certificates for authentication.
+      MUTUAL = 2;
+
+      // Similar to the passthrough mode, except servers with this TLS mode
+      // do not require an associated VirtualService to map from the SNI
+      // value to service in the registry. The destination details such as
+      // the service/subset/port are encoded in the SNI value. The proxy
+      // will forward to the upstream (Envoy) cluster (a group of
+      // endpoints) specified by the SNI value. This server is typically
+      // used to provide connectivity between services in disparate L3
+      // networks that otherwise do not have direct connectivity between
+      // their respective endpoints. Use of this mode assumes that both the
+      // source and the destination are using Istio mTLS to secure traffic.
+      AUTO_PASSTHROUGH = 3;
+    };
+
+    // Optional: Indicates whether connections to this port should be
+    // secured using TLS. The value of this field determines how TLS is
+    // enforced.
+    TLSmode mode = 2;
+
+    // Extra comment.
+
+    // REQUIRED if mode is `SIMPLE` or `MUTUAL`. The path to the file
+    // holding the server-side TLS certificate to use.
+    string server_certificate = 3;
+
+    // REQUIRED if mode is `SIMPLE` or `MUTUAL`. The path to the file
+    // holding the server's private key.
+    string private_key = 4;
+
+    // REQUIRED if mode is `MUTUAL`. The path to a file containing
+    // certificate authority certificates to use in verifying a presented
+    // client side certificate.
+    string ca_certificates = 5;
+
+    // The credentialName stands for a unique identifier that can be used
+    // to identify the serverCertificate and the privateKey. The
+    // credentialName appended with suffix "-cacert" is used to identify
+    // the CaCertificates associated with this server. Gateway workloads
+    // capable of fetching credentials from a remote credential store such
+    // as Kubernetes secrets, will be configured to retrieve the
+    // serverCertificate and the privateKey using credentialName, instead
+    // of using the file system paths specified above. If using mutual TLS,
+    // gateway workload instances will retrieve the CaCertificates using
+    // credentialName-cacert. The semantics of the name are platform
+    // dependent.  In Kubernetes, the default Istio supplied credential
+    // server expects the credentialName to match the name of the
+    // Kubernetes secret that holds the server certificate, the private
+    // key, and the CA certificate (if using mutual TLS). Set the
+    // `ISTIO_META_USER_SDS` metadata variable in the gateway's proxy to
+    // enable the dynamic credential fetching feature.
+    string credential_name = 10;
+
+    // A list of alternate names to verify the subject identity in the
+    // certificate presented by the client.
+    repeated string subject_alt_names = 6;
+
+    // TLS protocol versions.
+    enum TLSProtocol {
+      TLS_AUTO = 0; // Automatically choose the optimal TLS version.
+
+      TLSV1_0 = 1; // TLS version 1.0
+
+      TLSV1_1 = 2; // TLS version 1.1
+    
+      TLSV1_2 = 3; // TLS version 1.2
+
+      TLSV1_3 = 4; // TLS version 1.3
+    }
+
+    // Optional: Minimum TLS protocol version.
+    TLSProtocol min_protocol_version = 7;
+
+    // Optional: Maximum TLS protocol version.
+    TLSProtocol max_protocol_version = 8;
+
+    // Optional: If specified, only support the specified cipher list.
+    // Otherwise default to the default cipher list supported by Envoy.
+    repeated string cipher_suites = 9;
+  }
+
+  // Set of TLS related options that govern the server's behavior. Use
+  // these options to control if all http requests should be redirected to
+  // https, and the TLS modes to use.
+  TLSOptions tls = 3;
+
+  // The loopback IP endpoint or Unix domain socket to which traffic should
+  // be forwarded to by default. Format should be `127.0.0.1:PORT` or
+  // `unix:///path/to/socket` or `unix://@foobar` (Linux abstract namespace).
+  string default_endpoint = 5;
+}
+
+
+// Port describes the properties of a specific port of a service.
+message Port {
+  // REQUIRED: A valid non-negative integer port number.
+  uint32 number = 1;
+
+  // REQUIRED: The protocol exposed on the port.
+  // MUST BE one of HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS.
+  // TLS implies the connection will be routed based on the SNI header to
+  // the destination without terminating the TLS connection.
+  string protocol = 2;
+
+  // Label assigned to the port.
+  string name = 3;
+}