# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc

import api_pb2 as api__pb2


class AFTLogStub(object):
  # missing associated documentation comment in .proto file
  pass

  def __init__(self, channel):
    """Constructor.

    Args:
      channel: A grpc.Channel.
    """
    self.AddVBMeta = channel.unary_unary(
        '/aftl.AFTLog/AddVBMeta',
        request_serializer=api__pb2.AddVBMetaRequest.SerializeToString,
        response_deserializer=api__pb2.AddVBMetaResponse.FromString,
        )
    self.AnnotateVBMetaWithBuild = channel.stream_unary(
        '/aftl.AFTLog/AnnotateVBMetaWithBuild',
        request_serializer=api__pb2.AnnotateVBMetaWithBuildResponse.SerializeToString,
        response_deserializer=api__pb2.AnnotateVBMetaWithBuildResponse.FromString,
        )


class AFTLogServicer(object):
  # missing associated documentation comment in .proto file
  pass

  def AddVBMeta(self, request, context):
    """Insert a new VBMeta structure into the log.
    This request will effectively create 2 log entries:
    - VBMeta itself
    - Vendor annotations, which includes a reference to the VBMeta.
    """
    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
    context.set_details('Method not implemented!')
    raise NotImplementedError('Method not implemented!')

  def AnnotateVBMetaWithBuild(self, request_iterator, context):
    """Upload (or copy) the complete firmware image.
    """
    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
    context.set_details('Method not implemented!')
    raise NotImplementedError('Method not implemented!')


def add_AFTLogServicer_to_server(servicer, server):
  rpc_method_handlers = {
      'AddVBMeta': grpc.unary_unary_rpc_method_handler(
          servicer.AddVBMeta,
          request_deserializer=api__pb2.AddVBMetaRequest.FromString,
          response_serializer=api__pb2.AddVBMetaResponse.SerializeToString,
      ),
      'AnnotateVBMetaWithBuild': grpc.stream_unary_rpc_method_handler(
          servicer.AnnotateVBMetaWithBuild,
          request_deserializer=api__pb2.AnnotateVBMetaWithBuildResponse.FromString,
          response_serializer=api__pb2.AnnotateVBMetaWithBuildResponse.SerializeToString,
      ),
  }
  generic_handler = grpc.method_handlers_generic_handler(
      'aftl.AFTLog', rpc_method_handlers)
  server.add_generic_rpc_handlers((generic_handler,))
